KiCad PCB EDA Suite
readgerb.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2007-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <fctsys.h>
26 #include <common.h>
27 #include <confirm.h>
28 #include <kicad_string.h>
29 #include <gerbview.h>
30 #include <gerbview_frame.h>
31 #include <gerber_file_image.h>
32 #include <gerber_file_image_list.h>
33 #include <view/view.h>
34 
35 #include <html_messagebox.h>
36 #include <macros.h>
37 
38 /* Read a gerber file, RS274D, RS274X or RS274X2 format.
39  */
40 bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
41 {
42  wxString msg;
43 
44  int layer = GetActiveLayer();
46  GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
47 
48  if( gerber != NULL )
49  {
50  Erase_Current_DrawLayer( false );
51  }
52 
53  gerber = new GERBER_FILE_IMAGE( layer );
54  images->AddGbrImage( gerber, layer );
55 
56  /* Read the gerber file */
57  bool success = gerber->LoadGerberFile( GERBER_FullFileName );
58 
59  if( !success )
60  {
61  msg.Printf( _( "File \"%s\" not found" ), GetChars( GERBER_FullFileName ) );
62  DisplayError( this, msg, 10 );
63  return false;
64  }
65 
66  // Display errors list
67  if( gerber->GetMessages().size() > 0 )
68  {
69  HTML_MESSAGE_BOX dlg( this, _("Errors") );
70  dlg.ListSet(gerber->GetMessages());
71  dlg.ShowModal();
72  }
73 
74  /* if the gerber file is only a RS274D file
75  * (i.e. without any aperture information, but with items), warn the user:
76  */
77  if( !gerber->m_Has_DCode && gerber->GetItemsList() )
78  {
79  msg = _("Warning: this file has no D-Code definition\n"
80  "It is perhaps an old RS274D file\n"
81  "Therefore the size of items is undefined");
82  wxMessageBox( msg );
83  }
84 
85  auto canvas = GetGalCanvas();
86  if( canvas )
87  {
88  auto view = canvas->GetView();
89 
90  if( gerber->m_ImageNegative )
91  {
92  // TODO: find a way to handle negative images
93  // (maybe convert geometry into positives?)
94  }
95 
96  for( auto item = gerber->GetItemsList(); item; item = item->Next() )
97  {
98  view->Add( (KIGFX::VIEW_ITEM*) item );
99  }
100  }
101 
102  return true;
103 }
104 
105 
106 
107 // size of a single line of text from a gerber file.
108 // warning: some files can have *very long* lines, so the buffer must be large.
109 #define GERBER_BUFZ 1000000
110 // A large buffer to store one line
111 static char lineBuffer[GERBER_BUFZ+1];
112 
113 bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
114 {
115  int G_command = 0; // command number for G commands like G04
116  int D_commande = 0; // command number for D commands like D02
117  char* text;
118 
119  ClearMessageList( );
120  ResetDefaultValues();
121 
122  // Read the gerber file */
123  m_Current_File = wxFopen( aFullFileName, wxT( "rt" ) );
124 
125  if( m_Current_File == 0 )
126  return false;
127 
128  m_FileName = aFullFileName;
129 
130  LOCALE_IO toggleIo;
131 
132  wxString msg;
133 
134  while( true )
135  {
136  if( fgets( lineBuffer, GERBER_BUFZ, m_Current_File ) == NULL )
137  break;
138 
139  m_LineNum++;
140  text = StrPurge( lineBuffer );
141 
142  while( text && *text )
143  {
144  switch( *text )
145  {
146  case ' ':
147  case '\r':
148  case '\n':
149  text++;
150  break;
151 
152  case '*': // End command
153  m_CommandState = END_BLOCK;
154  text++;
155  break;
156 
157  case 'M': // End file
158  m_CommandState = CMD_IDLE;
159  while( *text )
160  text++;
161  break;
162 
163  case 'G': /* Line type Gxx : command */
164  G_command = GCodeNumber( text );
165  Execute_G_Command( text, G_command );
166  break;
167 
168  case 'D': /* Line type Dxx : Tool selection (xx > 0) or
169  * command if xx = 0..9 */
170  D_commande = DCodeNumber( text );
171  Execute_DCODE_Command( text, D_commande );
172  break;
173 
174  case 'X':
175  case 'Y': /* Move or draw command */
176  m_CurrentPos = ReadXYCoord( text );
177  if( *text == '*' ) // command like X12550Y19250*
178  {
179  Execute_DCODE_Command( text, m_Last_Pen_Command );
180  }
181  break;
182 
183  case 'I':
184  case 'J': /* Auxiliary Move command */
185  m_IJPos = ReadIJCoord( text );
186 
187  if( *text == '*' ) // command like X35142Y15945J504*
188  {
189  Execute_DCODE_Command( text, m_Last_Pen_Command );
190  }
191  break;
192 
193  case '%':
194  if( m_CommandState != ENTER_RS274X_CMD )
195  {
196  m_CommandState = ENTER_RS274X_CMD;
197  ReadRS274XCommand( lineBuffer, GERBER_BUFZ, text );
198  }
199  else //Error
200  {
201  AddMessageToList( wxT("Expected RS274X Command") );
202  m_CommandState = CMD_IDLE;
203  text++;
204  }
205  break;
206 
207  default:
208  text++;
209  msg.Printf( wxT("Unexpected symbol <%c>"), *text );
210  AddMessageToList( msg );
211  break;
212  }
213  }
214  }
215 
216  fclose( m_Current_File );
217 
218  m_InUse = true;
219 
220  return true;
221 }
char * StrPurge(char *text)
Function StrPurge removes leading and training spaces, tabs and end of line chars in text return a po...
Definition: string.cpp:194
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
This file is part of the common library.
bool Read_GERBER_File(const wxString &GERBER_FullFileName)
Definition: readgerb.cpp:40
Class GERBER_FILE_IMAGE holds the Image data and parameters for one gerber file and layer parameters ...
int AddGbrImage(GERBER_FILE_IMAGE *aGbrImage, int aIdx)
Add a GERBER_FILE_IMAGE* at index aIdx or at the first free location if aIdx < 0. ...
Class VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW...
Definition: view_item.h:84
void Erase_Current_DrawLayer(bool query)
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
int GetActiveLayer()
Function SetActiveLayer returns the active layer.
This file contains miscellaneous commonly used macros and functions.
void ClearMessageList()
Function ClearMessageList Clear the message list Call it before reading a Gerber file.
static char lineBuffer[GERBER_BUFZ+1]
Definition: readgerb.cpp:111
void ListSet(const wxString &aList)
Function ListSet Add a list of items.
bool LoadGerberFile(const wxString &aFullFileName)
Read and load a gerber file.
Definition: readgerb.cpp:113
const wxArrayString & GetMessages() const
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
GERBER_DRAW_ITEM * Next() const
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Accessors to GERBER_FILE_IMAGE_LIST and GERBER_FILE_IMAGE data.
#define GERBER_BUFZ
Definition: readgerb.cpp:109
Class HTML_MESSAGE_BOX.
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
GERBER_DRAW_ITEM * GetItemsList()
Function GetItemsList.
The common library.
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Function GetGalCanvas returns a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:895
GERBER_FILE_IMAGE * GetGbrImage(int aIdx) const
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:185