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 <kicad_string.h>
26 #include <gerbview.h>
27 #include <gerbview_frame.h>
28 #include <gerber_file_image.h>
29 #include <gerber_file_image_list.h>
30 #include <view/view.h>
31 
32 #include <html_messagebox.h>
33 #include <macros.h>
34 
35 #include <wx/msgdlg.h>
36 
37 /* Read a gerber file, RS274D, RS274X or RS274X2 format.
38  */
39 bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
40 {
41  wxString msg;
42 
43  int layer = GetActiveLayer();
45  GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
46 
47  if( gerber != NULL )
48  {
49  Erase_Current_DrawLayer( false );
50  }
51 
52  gerber = new GERBER_FILE_IMAGE( layer );
53 
54  // Read the gerber file. The image will be added only if it can be read
55  // to avoid broken data.
56  bool success = gerber->LoadGerberFile( GERBER_FullFileName );
57 
58  if( !success )
59  {
60  delete gerber;
61  msg.Printf( _( "File \"%s\" not found" ), GERBER_FullFileName );
62  ShowInfoBarError( msg );
63  return false;
64  }
65 
66  images->AddGbrImage( gerber, layer );
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 has items using D codes but missing D codes definitions,
77  * it can be a deprecated RS274D file (i.e. without any aperture information),
78  * or has missing definitions,
79  * warn the user:
80  */
81  if( gerber->GetItemsCount() && gerber->m_Has_MissingDCode )
82  {
83  if( !gerber->m_Has_DCode )
84  msg = _("Warning: this file has no D-Code definition\n"
85  "Therefore the size of some items is undefined");
86  else
87  msg = _("Warning: this file has some missing D-Code definitions\n"
88  "Therefore the size of some items is undefined");
89 
90  wxMessageBox( msg );
91  }
92 
93  if( GetCanvas() )
94  {
95  if( gerber->m_ImageNegative )
96  {
97  // TODO: find a way to handle negative images
98  // (maybe convert geometry into positives?)
99  }
100 
101  for( auto item : gerber->GetItems() )
102  GetCanvas()->GetView()->Add( (KIGFX::VIEW_ITEM*) item );
103  }
104 
105  return true;
106 }
107 
108 
109 
110 // size of a single line of text from a gerber file.
111 // warning: some files can have *very long* lines, so the buffer must be large.
112 #define GERBER_BUFZ 1000000
113 // A large buffer to store one line
114 static char lineBuffer[GERBER_BUFZ+1];
115 
116 bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
117 {
118  int G_command = 0; // command number for G commands like G04
119  int D_commande = 0; // command number for D commands like D02
120  char* text;
121 
122  ClearMessageList( );
124 
125  // Read the gerber file */
126  m_Current_File = wxFopen( aFullFileName, wxT( "rt" ) );
127 
128  if( m_Current_File == 0 )
129  return false;
130 
131  m_FileName = aFullFileName;
132 
133  LOCALE_IO toggleIo;
134 
135  wxString msg;
136 
137  while( true )
138  {
139  if( fgets( lineBuffer, GERBER_BUFZ, m_Current_File ) == NULL )
140  break;
141 
142  m_LineNum++;
143  text = StrPurge( lineBuffer );
144 
145  while( text && *text )
146  {
147  switch( *text )
148  {
149  case ' ':
150  case '\r':
151  case '\n':
152  text++;
153  break;
154 
155  case '*': // End command
157  text++;
158  break;
159 
160  case 'M': // End file
162  while( *text )
163  text++;
164  break;
165 
166  case 'G': /* Line type Gxx : command */
167  G_command = GCodeNumber( text );
168  Execute_G_Command( text, G_command );
169  break;
170 
171  case 'D': /* Line type Dxx : Tool selection (xx > 0) or
172  * command if xx = 0..9 */
173  D_commande = DCodeNumber( text );
174  Execute_DCODE_Command( text, D_commande );
175  break;
176 
177  case 'X':
178  case 'Y': /* Move or draw command */
179  m_CurrentPos = ReadXYCoord( text );
180  if( *text == '*' ) // command like X12550Y19250*
181  {
183  }
184  break;
185 
186  case 'I':
187  case 'J': /* Auxiliary Move command */
188  m_IJPos = ReadIJCoord( text );
189 
190  if( *text == '*' ) // command like X35142Y15945J504*
191  {
193  }
194  break;
195 
196  case '%':
198  {
201  }
202  else //Error
203  {
204  AddMessageToList( "Expected RS274X Command" );
206  text++;
207  }
208  break;
209 
210  default:
211  msg.Printf( "Unexpected char 0x%2.2X &lt;%c&lt;", *text, *text );
212  AddMessageToList( msg );
213  text++;
214  break;
215  }
216  }
217  }
218 
219  fclose( m_Current_File );
220 
221  m_InUse = true;
222 
223  return true;
224 }
void AddMessageToList(const wxString &aMessage)
Function AddMessageToList Add a message to the message list.
bool Execute_DCODE_Command(char *&text, int D_command)
Definition: rs274d.cpp:584
char * StrPurge(char *text)
Remove leading and training spaces, tabs and end of line chars in text.
Definition: string.cpp:364
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:222
GERBER_DRAW_ITEMS & GetItems()
wxPoint ReadIJCoord(char *&Text)
Returns the current coordinate type pointed to by InnJnn Text (InnnnJmmmm) These coordinates are rela...
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
bool Read_GERBER_File(const wxString &GERBER_FullFileName)
Definition: readgerb.cpp:39
GERBER_FILE_IMAGE holds the Image data and parameters for one gerber file and layer parameters (TODO:...
void ClearMessageList()
Function ClearMessageList Clear the message list Call it before reading a Gerber file.
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.
VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:85
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...
This file contains miscellaneous commonly used macros and functions.
int GCodeNumber(char *&Text)
Definition: rs274d.cpp:408
static char lineBuffer[GERBER_BUFZ+1]
Definition: readgerb.cpp:114
#define NULL
int DCodeNumber(char *&Text)
Definition: rs274d.cpp:431
const wxArrayString & GetMessages() const
void ListSet(const wxString &aList)
Add a list of items.
GERBER_FILE_IMAGE * GetGbrImage(int aIdx) const
bool LoadGerberFile(const wxString &aFullFileName)
Read and load a gerber file.
Definition: readgerb.cpp:116
virtual KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
#define GERBER_BUFZ
Definition: readgerb.cpp:112
HTML_MESSAGE_BOX.
void ShowInfoBarError(const wxString &aErrorMsg)
wxPoint ReadXYCoord(char *&aText, bool aExcellonMode=false)
Function ReadXYCoord Returns the current coordinate type pointed to by XnnYnn Text (XnnnnYmmmm)
int GetActiveLayer() const
Function SetActiveLayer returns the active layer.
bool Execute_G_Command(char *&text, int G_command)
Definition: rs274d.cpp:451
#define _(s)
Definition: 3d_actions.cpp:33
bool ReadRS274XCommand(char *aBuff, unsigned int aBuffSize, char *&aText)
reads a single RS274X command terminated with a %
Definition: rs274x.cpp:141
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:327
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Accessors to GERBER_FILE_IMAGE_LIST and GERBER_FILE_IMAGE data.
virtual void ResetDefaultValues()