gerbv
export-geda-pcb.c
Go to the documentation of this file.
1 /*
2  * gEDA - GNU Electronic Design Automation
3  * This file is a part of Gerbv.
4  *
5  * Copyright (C) 2014 Sergey Alyoshin
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (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, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20  */
21 
27 #include "gerbv.h"
28 #include "common.h"
29 
30 #include <glib/gstdio.h>
31 
32 static void
33 write_line(FILE *fd, gerbv_net_t *net, double thick,
34  double dx_p, double dy_m, const char *sflags)
35 {
36  dx_p = COORD2MILS(dx_p);
37  dy_m = COORD2MILS(dy_m);
38 
39  fprintf(fd, "\tLine[%.2fmil %.2fmil %.2fmil %.2fmil "
40  "%.2fmil %.2fmil \"%s\"]\n",
41  dx_p + COORD2MILS(net->stop_x),
42  dy_m - COORD2MILS(net->stop_y),
43  dx_p + COORD2MILS(net->start_x),
44  dy_m - COORD2MILS(net->start_y),
45  COORD2MILS(thick), 100.0, sflags);
46 }
47 
48 static void
49 write_element_with_pad(FILE *fd, gerbv_net_t *net, double thick,
50  double dx_p, double dy_m, const char *sflags)
51 {
52  double xc, yc;
53  static unsigned int element_num = 1;
54 
55  dx_p = COORD2MILS(dx_p);
56  dy_m = COORD2MILS(dy_m);
57 
58  xc = COORD2MILS(net->stop_x + net->start_x)/2;
59  yc = COORD2MILS(net->stop_y + net->start_y)/2;
60 
61  fprintf(fd, "Element[\"\" \"\" \"pad%d\" \"\" "
62  "%.2fmil %.2fmil 0mil 0mil 0 100 \"\"]\n(\n",
63  element_num++, dx_p + xc, dy_m - yc);
64  fprintf(fd, "\tPad[%.2fmil %.2fmil %.2fmil %.2fmil "
65  "%.2fmil 0mil %.2fmil "
66  "\"%s\" \"%s\" \"%s\"]\n)\n",
67  xc - COORD2MILS(net->stop_x),
68  yc - COORD2MILS(net->stop_y),
69  xc - COORD2MILS(net->start_x),
70  yc - COORD2MILS(net->start_y),
71  COORD2MILS(thick), /* Thickness */
72  COORD2MILS(thick), /* Mask */
73  "1", /* Name */
74  "1", /* Number */
75  sflags); /* String flags */
76 }
77 
78 static void
79 write_polygon(FILE *fd, gerbv_net_t *net,
80  double dx_p, double dy_m, const char *sflags)
81 {
82  dx_p = COORD2MILS(dx_p);
83  dy_m = COORD2MILS(dy_m);
84 
85  fprintf(fd, "\tPolygon(\"%s\")\n\t(", sflags);
86  net = net->next;
87 
88  unsigned int i = 0;
89  while (net != NULL
92  fprintf(fd, "%s[%.2fmil %.2fmil] ",
93  !(i%5)? "\n\t\t": "",
94  dx_p + COORD2MILS(net->stop_x),
95  dy_m - COORD2MILS(net->stop_y));
96  i++;
97  }
98  net = net->next;
99  }
100 
101  fprintf(fd, "\n\t)\n");
102 }
103 
104 gboolean
106  gerbv_image_t *input_img,
108 {
109  gerbv_aperture_t *apert;
110  gerbv_image_t *img;
111  gerbv_net_t *net;
112  double dx_p, dy_m;
113  double thick, len;
114  FILE *fd;
115 
116  if ((fd = g_fopen(file_name, "w")) == NULL) {
117  GERB_MESSAGE(_("Can't open file for writing: %s"), file_name);
118  return FALSE;
119  }
120 
121  /* Output decimals as dots for all locales */
122  setlocale(LC_NUMERIC, "C");
123 
124  /* Duplicate the image, cleaning it in the process */
125  img = gerbv_image_duplicate_image(input_img, trans);
126 
127  /* Header */
128  fputs("# Generated with gerbv\n\n", fd);
129  fputs("FileVersion[20091103]\n", fd);
130 
131  dx_p = (img->info->max_x - img->info->min_x) - img->info->min_x;
132  dy_m = 2*(img->info->max_y - img->info->min_y) + img->info->min_y;
133 
134  /* Make board size is 3 times more than Gerber size */
135  fprintf(fd, "PCB[\"%s\" %.2fmil %.2fmil]\n",
136  img->info->name,
137  3*COORD2MILS(img->info->max_x - img->info->min_x),
138  3*COORD2MILS(img->info->max_y - img->info->min_y));
139 
140  fputs("Grid[1000.000000 0.0000 0.0000 0]\n", fd);
141 
142  /* Write all apertures as elements with single pad, before layer
143  * definition */
144  for (net = img->netlist; net != NULL; net = net->next) {
145  apert = img->aperture[net->aperture];
146  if (!apert)
147  continue;
148 
149  /* Skip polygon, it will be written in layer section */
151  /* Skip to the end for polygon */
152  do {
153  net = net->next;
154  } while (net != NULL && net->interpolation !=
156  continue;
157  }
158 
159  switch (net->aperture_state) {
161  switch (apert->type) {
162  case GERBV_APTYPE_CIRCLE:
163  /* Set start to stop coords for Circle flash */
164  net->start_x = net->stop_x;
165  net->start_y = net->stop_y;
166  write_element_with_pad(fd, net,
167  apert->parameter[0],
168  dx_p, dy_m, "");
169  break;
170  case GERBV_APTYPE_OVAL:
172 
173  if (apert->parameter[0] > apert->parameter[1]) {
174  /* Horizontal */
175  len = apert->parameter[0];
176  thick = apert->parameter[1];
177 
178  net->start_x = net->stop_x - len/2 +
179  thick/2;
180  net->stop_x += len/2 - thick/2;
181  net->start_y = net->stop_y;
182  } else {
183  /* Vertical */
184  len = apert->parameter[1];
185  thick = apert->parameter[0];
186 
187  net->start_x = net->stop_x;
188  net->start_y = net->stop_y - len/2 +
189  thick/2;
190  net->stop_y += len/2 - thick/2;
191  }
192 
193  write_element_with_pad(fd, net, thick,
194  dx_p, dy_m,
195  (apert->type == GERBV_APTYPE_RECTANGLE)?
196  "square": "");
197  break;
198  default:
199 /* TODO */
200  GERB_COMPILE_WARNING(
201  "%s:%d: aperture type %d is "
202  "not yet supported",
203  __func__, __LINE__,
204  apert->type);
205  break;
206  }
207  break;
209  /* Will be done in layer section */
210  break;
211  default:
212 /* TODO */
213  GERB_COMPILE_WARNING(
214  "%s:%d: aperture type %d is "
215  "not yet supported",
216  __func__, __LINE__,
217  apert->type);
218  break;
219  }
220  }
221 
222  /* Write all lines in layer definition */
223  fputs("Layer(1 \"top\")\n(\n", fd);
224 
225  for (net = img->netlist; net != NULL; net = net->next) {
226  apert = img->aperture[net->aperture];
227  if (!apert)
228  continue;
229 
231  write_polygon(fd, net, dx_p, dy_m, "clearpoly");
232 
233  /* Skip to the end for polygon */
234  do {
235  net = net->next;
236  } while (net != NULL && net->interpolation !=
238  continue;
239  }
240 
241  switch (net->aperture_state) {
243  /* Already done in elements section */
244  break;
245 
247  /* Trace (or cut slot in drill file) */
248  switch (apert->type) {
249  case GERBV_APTYPE_CIRCLE:
250  write_line(fd, net, apert->parameter[0],
251  dx_p, dy_m, "clearline");
252  break;
253  default:
254  GERB_COMPILE_WARNING(
255  "%s:%d: aperture type %d is "
256  "not yet supported",
257  __func__, __LINE__,
258  apert->type);
259  break;
260  }
261  break;
262  default:
263  GERB_COMPILE_WARNING(
264  "%s:%d: aperture state %d type %d is "
265  "not yet supported",
266  __func__, __LINE__,
267  net->aperture_state, apert->type);
268  break;
269  }
270  }
271 
272  fputs(")\n", fd); /* End of Layer 1 */
273 
274  /* Necessary layer */
275  fputs("Layer(7 \"outline\")\n(\n)\n", fd);
276 
277  gerbv_destroy_image (img);
278  fclose(fd);
279 
280  setlocale(LC_NUMERIC, ""); /* Return to the default locale */
281 
282  return TRUE;
283 }
gboolean gerbv_export_geda_pcb_file_from_image(const gchar *file_name, gerbv_image_t *input_img, gerbv_user_transformation_t *trans)
Export an image to a new file in gEDA PCB format.
void gerbv_destroy_image(gerbv_image_t *image)
Free an image structure.
Definition: gerb_image.c:106
gerbv_image_t * gerbv_image_duplicate_image(gerbv_image_t *sourceImage, gerbv_user_transformation_t *transform)
Duplicate an existing image and return the new copy.
Definition: gerb_image.c:920
The main header file for the libgerbv library.
@ GERBV_APERTURE_STATE_ON
Definition: gerbv.h:179
@ GERBV_APERTURE_STATE_FLASH
Definition: gerbv.h:180
@ GERBV_APTYPE_OVAL
Definition: gerbv.h:162
@ GERBV_APTYPE_CIRCLE
Definition: gerbv.h:160
@ GERBV_APTYPE_RECTANGLE
Definition: gerbv.h:161
@ GERBV_INTERPOLATION_PAREA_START
Definition: gerbv.h:308
@ GERBV_INTERPOLATION_PAREA_END
Definition: gerbv.h:309
gerbv_net_t * netlist
Definition: gerbv.h:729
gerbv_aperture_t * aperture[APERTURE_MAX]
Definition: gerbv.h:723
gerbv_image_info_t * info
Definition: gerbv.h:728
double stop_y
Definition: gerbv.h:660
gerbv_aperture_state_t aperture_state
Definition: gerbv.h:663
double stop_x
Definition: gerbv.h:659
double start_x
Definition: gerbv.h:657
struct gerbv_net * next
Definition: gerbv.h:666
double start_y
Definition: gerbv.h:658
gerbv_interpolation_t interpolation
Definition: gerbv.h:664
int aperture
Definition: gerbv.h:662