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  gerber = new GERBER_FILE_IMAGE( layer );
51  images->AddGbrImage( gerber, layer );
52  }
53  else
54  {
55  Erase_Current_DrawLayer( false );
56  }
57 
58  /* Read the gerber file */
59  bool success = gerber->LoadGerberFile( GERBER_FullFileName );
60 
61  if( !success )
62  {
63  msg.Printf( _( "File \"%s\" not found" ), GetChars( GERBER_FullFileName ) );
64  DisplayError( this, msg, 10 );
65  return false;
66  }
67 
68  // Display errors list
69  if( gerber->GetMessages().size() > 0 )
70  {
71  HTML_MESSAGE_BOX dlg( this, _("Errors") );
72  dlg.ListSet(gerber->GetMessages());
73  dlg.ShowModal();
74  }
75 
76  /* if the gerber file is only a RS274D file
77  * (i.e. without any aperture information, but with items), warn the user:
78  */
79  if( !gerber->m_Has_DCode && gerber->GetItemsList() )
80  {
81  msg = _("Warning: this file has no D-Code definition\n"
82  "It is perhaps an old RS274D file\n"
83  "Therefore the size of items is undefined");
84  wxMessageBox( msg );
85  }
86 
87  auto canvas = GetGalCanvas();
88  if( canvas )
89  {
90  auto view = canvas->GetView();
91 
92  if( gerber->m_ImageNegative )
93  {
94  // TODO: find a way to handle negative images
95  // (maybe convert geometry into positives?)
96  }
97 
98  for( auto item = gerber->GetItemsList(); item; item = item->Next() )
99  {
100  view->Add( (KIGFX::VIEW_ITEM*) item );
101  }
102  }
103 
104  return true;
105 }
106 
107 
108 bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
109 {
110  int G_command = 0; // command number for G commands like G04
111  int D_commande = 0; // command number for D commands like D02
112  char line[GERBER_BUFZ];
113  char* text;
114 
115  ClearMessageList( );
116  ResetDefaultValues();
117 
118  // Read the gerber file */
119  m_Current_File = wxFopen( aFullFileName, wxT( "rt" ) );
120 
121  if( m_Current_File == 0 )
122  return false;
123 
124  m_FileName = aFullFileName;
125 
126  LOCALE_IO toggleIo;
127 
128  wxString msg;
129 
130  while( true )
131  {
132  if( fgets( line, sizeof(line), m_Current_File ) == NULL )
133  break;
134 
135  m_LineNum++;
136  text = StrPurge( line );
137 
138  while( text && *text )
139  {
140  switch( *text )
141  {
142  case ' ':
143  case '\r':
144  case '\n':
145  text++;
146  break;
147 
148  case '*': // End command
149  m_CommandState = END_BLOCK;
150  text++;
151  break;
152 
153  case 'M': // End file
154  m_CommandState = CMD_IDLE;
155  while( *text )
156  text++;
157  break;
158 
159  case 'G': /* Line type Gxx : command */
160  G_command = GCodeNumber( text );
161  Execute_G_Command( text, G_command );
162  break;
163 
164  case 'D': /* Line type Dxx : Tool selection (xx > 0) or
165  * command if xx = 0..9 */
166  D_commande = DCodeNumber( text );
167  Execute_DCODE_Command( text, D_commande );
168  break;
169 
170  case 'X':
171  case 'Y': /* Move or draw command */
172  m_CurrentPos = ReadXYCoord( text );
173  if( *text == '*' ) // command like X12550Y19250*
174  {
175  Execute_DCODE_Command( text,
176  m_Last_Pen_Command );
177  }
178  break;
179 
180  case 'I':
181  case 'J': /* Auxiliary Move command */
182  m_IJPos = ReadIJCoord( text );
183 
184  if( *text == '*' ) // command like X35142Y15945J504*
185  {
186  Execute_DCODE_Command( text,
187  m_Last_Pen_Command );
188  }
189  break;
190 
191  case '%':
192  if( m_CommandState != ENTER_RS274X_CMD )
193  {
194  m_CommandState = ENTER_RS274X_CMD;
195  ReadRS274XCommand( line, text );
196  }
197  else //Error
198  {
199  AddMessageToList( wxT("Expected RS274X Command") );
200  m_CommandState = CMD_IDLE;
201  text++;
202  }
203  break;
204 
205  default:
206  text++;
207  msg.Printf( wxT("Unexpected symbol <%c>"), *text );
208  AddMessageToList( msg );
209  break;
210  }
211  }
212  }
213 
214  fclose( m_Current_File );
215 
216  m_InUse = true;
217 
218  return true;
219 }
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:83
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.
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:108
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.
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.
#define GERBER_BUFZ
size of single line of a text from a gerber file.
Definition: gerbview.h:39
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Function GetGalCanvas returns a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:882
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:241