gerbv  2.10.1-dev~93f1b5
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, double dx_p, double dy_m, const char* sflags) {
34  dx_p = COORD2MILS(dx_p);
35  dy_m = COORD2MILS(dy_m);
36 
37  fprintf(
38  fd,
39  "\tLine[%.2fmil %.2fmil %.2fmil %.2fmil "
40  "%.2fmil %.2fmil \"%s\"]\n",
41  dx_p + COORD2MILS(net->stop_x), dy_m - COORD2MILS(net->stop_y), dx_p + COORD2MILS(net->start_x),
42  dy_m - COORD2MILS(net->start_y), COORD2MILS(thick), 100.0, sflags
43  );
44 }
45 
46 static void
47 write_element_with_pad(FILE* fd, gerbv_net_t* net, double thick, double dx_p, double dy_m, const char* sflags) {
48  double xc, yc;
49  static unsigned int element_num = 1;
50 
51  dx_p = COORD2MILS(dx_p);
52  dy_m = COORD2MILS(dy_m);
53 
54  xc = COORD2MILS(net->stop_x + net->start_x) / 2;
55  yc = COORD2MILS(net->stop_y + net->start_y) / 2;
56 
57  fprintf(
58  fd,
59  "Element[\"\" \"\" \"pad%d\" \"\" "
60  "%.2fmil %.2fmil 0mil 0mil 0 100 \"\"]\n(\n",
61  element_num++, dx_p + xc, dy_m - yc
62  );
63  fprintf(
64  fd,
65  "\tPad[%.2fmil %.2fmil %.2fmil %.2fmil "
66  "%.2fmil 0mil %.2fmil "
67  "\"%s\" \"%s\" \"%s\"]\n)\n",
68  xc - COORD2MILS(net->stop_x), yc - COORD2MILS(net->stop_y), xc - COORD2MILS(net->start_x),
69  yc - COORD2MILS(net->start_y), COORD2MILS(thick), /* Thickness */
70  COORD2MILS(thick), /* Mask */
71  "1", /* Name */
72  "1", /* Number */
73  sflags
74  ); /* String flags */
75 }
76 
77 static void
78 write_polygon(FILE* fd, gerbv_net_t* net, double dx_p, double dy_m, const char* sflags) {
79  dx_p = COORD2MILS(dx_p);
80  dy_m = COORD2MILS(dy_m);
81 
82  fprintf(fd, "\tPolygon(\"%s\")\n\t(", sflags);
83  net = net->next;
84 
85  unsigned int i = 0;
86  while (net != NULL && net->interpolation != GERBV_INTERPOLATION_PAREA_END) {
88  fprintf(
89  fd, "%s[%.2fmil %.2fmil] ", !(i % 5) ? "\n\t\t" : "", dx_p + COORD2MILS(net->stop_x),
90  dy_m - COORD2MILS(net->stop_y)
91  );
92  i++;
93  }
94  net = net->next;
95  }
96 
97  fprintf(fd, "\n\t)\n");
98 }
99 
100 gboolean
102  const gchar* file_name, gerbv_image_t* input_img, gerbv_user_transformation_t* trans
103 ) {
104  gerbv_aperture_t* apert;
105  gerbv_image_t* img;
106  gerbv_net_t* net;
107  double dx_p, dy_m;
108  double thick, len;
109  FILE* fd;
110 
111  if ((fd = g_fopen(file_name, "w")) == NULL) {
112  GERB_MESSAGE(_("Can't open file for writing: %s"), file_name);
113  return FALSE;
114  }
115 
116  /* Output decimals as dots for all locales */
117  setlocale(LC_NUMERIC, "C");
118 
119  /* Duplicate the image, cleaning it in the process */
120  img = gerbv_image_duplicate_image(input_img, trans);
121 
122  /* Header */
123  fputs("# Generated with gerbv\n\n", fd);
124  fputs("FileVersion[20091103]\n", fd);
125 
126  dx_p = (img->info->max_x - img->info->min_x) - img->info->min_x;
127  dy_m = 2 * (img->info->max_y - img->info->min_y) + img->info->min_y;
128 
129  /* Make board size is 3 times more than Gerber size */
130  fprintf(
131  fd, "PCB[\"%s\" %.2fmil %.2fmil]\n", img->info->name, 3 * COORD2MILS(img->info->max_x - img->info->min_x),
132  3 * COORD2MILS(img->info->max_y - img->info->min_y)
133  );
134 
135  fputs("Grid[1000.000000 0.0000 0.0000 0]\n", fd);
136 
137  /* Write all apertures as elements with single pad, before layer
138  * definition */
139  for (net = img->netlist; net != NULL; net = net->next) {
140  apert = img->aperture[net->aperture];
141  if (!apert)
142  continue;
143 
144  /* Skip polygon, it will be written in layer section */
146  /* Skip to the end for polygon */
147  do {
148  net = net->next;
149  } while (net != NULL && net->interpolation != GERBV_INTERPOLATION_PAREA_END);
150  continue;
151  }
152 
153  switch (net->aperture_state) {
155  switch (apert->type) {
156  case GERBV_APTYPE_CIRCLE:
157  /* Set start to stop coords for Circle flash */
158  net->start_x = net->stop_x;
159  net->start_y = net->stop_y;
160  write_element_with_pad(fd, net, apert->parameter[0], dx_p, dy_m, "");
161  break;
162  case GERBV_APTYPE_OVAL:
164 
165  if (apert->parameter[0] > apert->parameter[1]) {
166  /* Horizontal */
167  len = apert->parameter[0];
168  thick = apert->parameter[1];
169 
170  net->start_x = net->stop_x - len / 2 + thick / 2;
171  net->stop_x += len / 2 - thick / 2;
172  net->start_y = net->stop_y;
173  } else {
174  /* Vertical */
175  len = apert->parameter[1];
176  thick = apert->parameter[0];
177 
178  net->start_x = net->stop_x;
179  net->start_y = net->stop_y - len / 2 + thick / 2;
180  net->stop_y += len / 2 - thick / 2;
181  }
182 
183  write_element_with_pad(
184  fd, net, thick, dx_p, dy_m, (apert->type == GERBV_APTYPE_RECTANGLE) ? "square" : ""
185  );
186  break;
187  default:
188  /* TODO */
189  GERB_COMPILE_WARNING(
190  "%s:%d: aperture type %d is "
191  "not yet supported",
192  __func__, __LINE__, apert->type
193  );
194  break;
195  }
196  break;
198  /* Will be done in layer section */
199  break;
200  default:
201  /* TODO */
202  GERB_COMPILE_WARNING(
203  "%s:%d: aperture type %d is "
204  "not yet supported",
205  __func__, __LINE__, apert->type
206  );
207  break;
208  }
209  }
210 
211  /* Write all lines in layer definition */
212  fputs("Layer(1 \"top\")\n(\n", fd);
213 
214  for (net = img->netlist; net != NULL; net = net->next) {
215  apert = img->aperture[net->aperture];
216  if (!apert)
217  continue;
218 
220  write_polygon(fd, net, dx_p, dy_m, "clearpoly");
221 
222  /* Skip to the end for polygon */
223  do {
224  net = net->next;
225  } while (net != NULL && net->interpolation != GERBV_INTERPOLATION_PAREA_END);
226  continue;
227  }
228 
229  switch (net->aperture_state) {
231  /* Already done in elements section */
232  break;
233 
235  /* Trace (or cut slot in drill file) */
236  switch (apert->type) {
237  case GERBV_APTYPE_CIRCLE: write_line(fd, net, apert->parameter[0], dx_p, dy_m, "clearline"); break;
238  default:
239  GERB_COMPILE_WARNING(
240  "%s:%d: aperture type %d is "
241  "not yet supported",
242  __func__, __LINE__, apert->type
243  );
244  break;
245  }
246  break;
247  default:
248  GERB_COMPILE_WARNING(
249  "%s:%d: aperture state %d type %d is "
250  "not yet supported",
251  __func__, __LINE__, net->aperture_state, apert->type
252  );
253  break;
254  }
255  }
256 
257  fputs(")\n", fd); /* End of Layer 1 */
258 
259  /* Necessary layer */
260  fputs("Layer(7 \"outline\")\n(\n)\n", fd);
261 
262  gerbv_destroy_image(img);
263  fclose(fd);
264 
265  setlocale(LC_NUMERIC, ""); /* Return to the default locale */
266 
267  return TRUE;
268 }
Contains basic defines.
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:104
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:815
The main header file for the libgerbv library.
@ GERBV_APERTURE_STATE_ON
Definition: gerbv.h:172
@ GERBV_APERTURE_STATE_FLASH
Definition: gerbv.h:173
@ GERBV_APTYPE_OVAL
Definition: gerbv.h:154
@ GERBV_APTYPE_CIRCLE
Definition: gerbv.h:152
@ GERBV_APTYPE_RECTANGLE
Definition: gerbv.h:153
@ GERBV_INTERPOLATION_PAREA_START
Definition: gerbv.h:300
@ GERBV_INTERPOLATION_PAREA_END
Definition: gerbv.h:301
gerbv_net_t * netlist
Definition: gerbv.h:739
gerbv_aperture_t * aperture[APERTURE_MAX]
Definition: gerbv.h:733
gerbv_image_info_t * info
Definition: gerbv.h:738
double stop_y
Definition: gerbv.h:671
gerbv_aperture_state_t aperture_state
Definition: gerbv.h:674
double stop_x
Definition: gerbv.h:670
double start_x
Definition: gerbv.h:668
struct gerbv_net * next
Definition: gerbv.h:677
double start_y
Definition: gerbv.h:669
gerbv_interpolation_t interpolation
Definition: gerbv.h:675
int aperture
Definition: gerbv.h:673