KiCad PCB EDA Suite
gbr_metadata.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) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2016 KiCad Developers, see CHANGELOG.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 
31 #include <fctsys.h>
32 #include <plot_auxiliary_data.h>
33 
34 
36 {
37  std::string attribute_string;
38 
39  // generate a string to print a Gerber Aperture attribute
40  switch( aAttribute )
41  {
42  case GBR_APERTURE_ATTRIB_END: // Dummy value (aAttribute must be < GBR_APERTURE_ATTRIB_END)
43  case GBR_APERTURE_ATTRIB_NONE: // idle command: do nothing
44  break;
45 
46  case GBR_APERTURE_ATTRIB_ETCHEDCMP: // print info associated to an item
47  // which connects 2 different nets
48  // (Net tees, microwave component)
49  attribute_string = "%TA.AperFunction,EtchedComponent*%\n";
50  break;
51 
52  case GBR_APERTURE_ATTRIB_CONDUCTOR: // print info associated to a track
53  attribute_string = "%TA.AperFunction,Conductor*%\n";
54  break;
55 
56  case GBR_APERTURE_ATTRIB_CUTOUT: // print info associated to a outline
57  attribute_string = "%TA.AperFunction,CutOut*%\n";
58  break;
59 
60  case GBR_APERTURE_ATTRIB_VIAPAD: // print info associated to a flashed via
61  attribute_string = "%TA.AperFunction,ViaPad*%\n";
62  break;
63 
64  case GBR_APERTURE_ATTRIB_NONCONDUCTOR: // print info associated to a flashed pad
65  attribute_string = "%TA.AperFunction,NonConductor*%\n";
66  break;
67 
68  case GBR_APERTURE_ATTRIB_COMPONENTPAD: // print info associated to a flashed
69  // through hole component on outer layer
70  attribute_string = "%TA.AperFunction,ComponentPad*%\n";
71  break;
72 
73  case GBR_APERTURE_ATTRIB_SMDPAD_SMDEF: // print info associated to a flashed for SMD pad.
74  // with solder mask defined from the copper shape
75  // Excluded BGA pads which have their own type
76  attribute_string = "%TA.AperFunction,SMDPad,SMDef*%\n";
77  break;
78 
79  case GBR_APERTURE_ATTRIB_SMDPAD_CUDEF: // print info associated to a flashed SMD pad with
80  // a solder mask defined by the solder mask
81  attribute_string = "%TA.AperFunction,SMDPad,CuDef*%\n";
82  break;
83 
84  case GBR_APERTURE_ATTRIB_BGAPAD_SMDEF: // print info associated to flashed BGA pads with
85  // a solder mask defined by the copper shape
86  attribute_string = "%TA.AperFunction,BGAPad,SMDef*%\n";
87  break;
88 
89  case GBR_APERTURE_ATTRIB_BGAPAD_CUDEF: // print info associated to a flashed BGA pad with
90  // a solder mask defined by the solder mask
91  attribute_string = "%TA.AperFunction,BGAPad,CuDef*%\n";
92  break;
93 
94  case GBR_APERTURE_ATTRIB_CONNECTORPAD: // print info associated to a flashed edge connector pad (outer layers)
95  attribute_string = "%TA.AperFunction,ConnectorPad*%\n";
96  break;
97 
98  case GBR_APERTURE_ATTRIB_WASHERPAD: // print info associated to flashed mechanical pads (NPTH)
99  attribute_string = "%TA.AperFunction,WasherPad*%\n";
100  break;
101 
102  case GBR_APERTURE_ATTRIB_HEATSINKPAD: // print info associated to a flashed heat sink pad (typically for SMDs)
103  attribute_string = "%TA.AperFunction,HeatsinkPad*%\n";
104  break;
105  }
106 
107  return attribute_string;
108 }
109 
110 
111 std::string formatStringToGerber( const wxString& aString )
112 {
113  /* format string means convert any code > 0x7F and unautorized code to a hexadecimal
114  * 16 bits sequence unicode
115  * unautorized codes are ',' '*' '%' '\'
116  */
117  std::string txt;
118 
119  txt.reserve( aString.Length() );
120 
121  for( unsigned ii = 0; ii < aString.Length(); ++ii )
122  {
123  unsigned code = aString[ii];
124  bool convert = false;
125 
126  switch( code )
127  {
128  case '\\':
129  case '%':
130  case '*':
131  case ',':
132  convert = true;
133  break;
134 
135  default:
136  break;
137  }
138 
139  if( convert || code > 0x7F )
140  {
141  txt += '\\';
142 
143  // Convert code to 4 hexadecimal digit
144  // (Gerber allows only 4 hexadecimal digit)
145  char hexa[32];
146  sprintf( hexa,"%4.4X", code & 0xFFFF);
147  txt += hexa;
148  }
149  else
150  txt += char( code );
151  }
152 
153  return txt;
154 }
155 
156 // Netname and Pan num fields cannot be empty in Gerber files
157 // Normalized names must be used, if any
158 #define NO_NET_NAME wxT( "N/C" ) // net name of not connected pads (one pad net) (normalized)
159 #define NO_PAD_NAME wxT( "" ) // pad name of pads without pad name/number (not normalized)
160 
161 bool FormatNetAttribute( std::string& aPrintedText, std::string& aLastNetAttributes,
162  GBR_NETLIST_METADATA* aData, bool& aClearPreviousAttributes )
163 {
164  aClearPreviousAttributes = false;
165 
166  // print a Gerber net attribute record.
167  // it is added to the object attributes dictionnary
168  // On file, only modified or new attributes are printed.
169  if( aData == NULL )
170  return false;
171 
172  std::string pad_attribute_string;
173  std::string net_attribute_string;
174  std::string cmp_attribute_string;
175 
177  return false; // idle command: do nothing
178 
180  {
181  // print info associated to a flashed pad (cmpref, pad name)
182  // example: %TO.P,R5,3*%
183  pad_attribute_string = "%TO.P,";
184  pad_attribute_string += formatStringToGerber( aData->m_Cmpref ) + ",";
185 
186  if( aData->m_Padname.IsEmpty() )
187  // Happens for "mechanical" or never connected pads
188  pad_attribute_string += formatStringToGerber( NO_PAD_NAME );
189  else
190  pad_attribute_string += formatStringToGerber( aData->m_Padname );
191 
192  pad_attribute_string += "*%\n";
193  }
194 
196  {
197  // print info associated to a net
198  // example: %TO.N,Clk3*%
199  net_attribute_string = "%TO.N,";
200 
201  if( aData->m_Netname.IsEmpty() )
202  {
203  if( aData->m_NotInNet )
204  {
205  // Happens for not connectable pads: mechanical pads
206  // and pads with no padname/num
207  // In this case the net name must be left empty
208  }
209  else
210  {
211  // Happens for not connected pads: use a normalized
212  // dummy name
213  net_attribute_string += formatStringToGerber( NO_NET_NAME );
214  }
215  }
216  else
217  net_attribute_string += formatStringToGerber( aData->m_Netname );
218 
219  net_attribute_string += "*%\n";
220  }
221 
224  {
225  // print info associated to a footprint
226  // example: %TO.C,R2*%
227  // Because GBR_NETINFO_PAD option already contains this info, it is not
228  // created here for a GBR_NETINFO_PAD attribute
229  cmp_attribute_string = "%TO.C,";
230  cmp_attribute_string += formatStringToGerber( aData->m_Cmpref ) + "*%\n";
231  }
232 
233  // the full list of requested attributes:
234  std::string full_attribute_string = pad_attribute_string + net_attribute_string
235  + cmp_attribute_string;
236  // the short list of requested attributes
237  // (only modified or new attributes are stored here):
238  std::string short_attribute_string;
239 
240  if( aLastNetAttributes != full_attribute_string )
241  {
242  // first, remove no more existing attributes.
243  // Because in Kicad the full attribute list is evaluated for each object,
244  // the entire dictionnary is cleared
245  bool clearDict = false;
246 
247  if( aLastNetAttributes.find( "%TO.P," ) != std::string::npos )
248  {
249  if( pad_attribute_string.empty() ) // No more this attribute
250  clearDict = true;
251  else if( aLastNetAttributes.find( pad_attribute_string )
252  == std::string::npos ) // This attribute has changed
253  short_attribute_string += pad_attribute_string;
254  }
255  else // New attribute
256  short_attribute_string += pad_attribute_string;
257 
258  if( aLastNetAttributes.find( "%TO.N," ) != std::string::npos )
259  {
260  if( net_attribute_string.empty() ) // No more this attribute
261  clearDict = true;
262  else if( aLastNetAttributes.find( net_attribute_string )
263  == std::string::npos ) // This attribute has changed
264  short_attribute_string += net_attribute_string;
265  }
266  else // New attribute
267  short_attribute_string += net_attribute_string;
268 
269  if( aLastNetAttributes.find( "%TO.C," ) != std::string::npos )
270  {
271  if( cmp_attribute_string.empty() ) // No more this attribute
272  clearDict = true;
273  else if( aLastNetAttributes.find( cmp_attribute_string )
274  == std::string::npos ) // This attribute has changed
275  short_attribute_string += cmp_attribute_string;
276  }
277  else // New attribute
278  short_attribute_string += cmp_attribute_string;
279 
280  aClearPreviousAttributes = clearDict;
281 
282  aLastNetAttributes = full_attribute_string;
283 
284  if( clearDict )
285  aPrintedText = full_attribute_string;
286  else
287  aPrintedText = short_attribute_string;
288  }
289 
290  return true;
291 }
#define NO_NET_NAME
aperture used for edge connecto pad (outer layers)
aperture used for heat sink pad (typically for SMDs)
print info associated to a component (TO.C attribute)
wxString m_Cmpref
the component reference parent of the data
aperture used for through hole component on outer layer
std::string formatStringToGerber(const wxString &aString)
This helper function "normalize" aString and convert it to a Gerber std::string Normalisation means c...
aperture used for SMD pad. Excluded BGA pads which have their own type
aperture used for BGA pad with a solder mask defined by the solder mask
wxString m_Padname
for a flashed pad: the pad name ((TO.P attribute)
#define NO_PAD_NAME
bool FormatNetAttribute(std::string &aPrintedText, std::string &aLastNetAttributes, GBR_NETLIST_METADATA *aData, bool &aClearPreviousAttributes)
Generates the string to print to a gerber file, to set a net attribute for a graphic object...
wxString m_Netname
for items associated to a net: the netname
aperture used for mechanical pads (NPTH)
aperture used for BGA pads with a solder mask defined by the copper shape
aperture used for connected items like tracks (not vias)
aperture used for SMD pad with a solder mask defined by the solder mask
print info associated to a flashed pad (TO.P attribute)
bool m_NotInNet
true if a pad of a footprint cannot be connected (for instance a mechanical NPTH, ot a not named pad)...
aperture used for not connected items (texts, outlines on copper)
print info associated to a net (TO.N attribute)
int m_NetAttribType
the type of net info (used to define the gerber string to create)