gerbv  2.10.1-dev~93f1b5
export-dxf.cpp
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 
29 #include <iostream>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <math.h>
33 
34 #include <dxflib/dl_dxf.h>
35 
36 #include "common.h"
37 
38 /* dxflib version difference */
39 #ifndef DL_STRGRP_END
40 #define DL_STRGRP_END STRGRP_END
41 #endif
42 #ifndef DL_ATTFLAGS_CODE
43 #define DL_ATTFLAGS_CODE ATTFLAGS_CODE
44 #endif
45 #ifndef DL_TXTHI_CODE
46 #define DL_TXTHI_CODE TXTHI_CODE
47 #endif
48 #ifndef DL_TXT_STYLE_CODE
49 #define DL_TXT_STYLE_CODE TXT_STYLE_CODE
50 #endif
51 #ifndef DL_FIRST_XCOORD_CODE
52 #define DL_FIRST_XCOORD_CODE FIRST_XCOORD_CODE
53 #endif
54 #ifndef DL_FIRST_YCOORD_CODE
55 #define DL_FIRST_YCOORD_CODE FIRST_YCOORD_CODE
56 #endif
57 #ifndef DL_CLOSED_PLINE
58 #define DL_CLOSED_PLINE CLOSED_PLINE
59 #endif
60 
61 enum insunits {
62  INSUNITS_NONE = 0,
63  INSUNITS_INCH,
64  INSUNITS_FEET,
65  INSUNITS_MILE,
66  INSUNITS_MM,
67  INSUNITS_CM,
68  INSUNITS_M,
69  INSUNITS_KM,
70  INSUNITS_MICROINCH,
71  INSUNITS_MIL,
72  /* ... and more ... */
73 };
74 
75 extern "C" {
76 gboolean
77 gerbv_export_dxf_file_from_image(const gchar* file_name, gerbv_image_t* input_img, gerbv_user_transformation_t* trans) {
78  DL_Codes::version exportVersion = DL_Codes::AC1015;
79  DL_Dxf* dxf = new DL_Dxf();
80  DL_WriterA* dw;
81  gerbv_aperture_t* apert;
82  gerbv_image_t* img;
83  gerbv_net_t* net;
84  GArray* apert_tab;
85  double x[4], y[4], r, dx, dy, nom;
86  unsigned int i;
87 
88  dw = dxf->out(file_name, exportVersion);
89 
90  if (dw == NULL) {
91  GERB_MESSAGE(_("Can't open file for writing: %s"), file_name);
92  return FALSE;
93  }
94 
95  /* Output decimals as dots for all locales */
96  setlocale(LC_NUMERIC, "C");
97 
98  /* Duplicate the image, cleaning it in the process */
99  img = gerbv_image_duplicate_image(input_img, trans);
100 
101  dxf->writeHeader(*dw);
102 
103  dw->dxfString(DL_STRGRP_END, "$INSUNITS");
104  dw->dxfInt(DL_ATTFLAGS_CODE, INSUNITS_INCH);
105 
106  dw->dxfString(DL_STRGRP_END, "$DIMEXE");
107  dw->dxfReal(DL_TXTHI_CODE, 1.25);
108 
109  dw->dxfString(DL_STRGRP_END, "$TEXTSTYLE");
110  dw->dxfString(DL_TXT_STYLE_CODE, "Standard");
111 
112  /* TODO ? */
113  dw->dxfString(DL_STRGRP_END, "$LIMMIN");
114  dw->dxfReal(DL_FIRST_XCOORD_CODE, 0.0);
115  dw->dxfReal(DL_FIRST_YCOORD_CODE, 0.0);
116 
117  dw->sectionEnd();
118 
119  dw->sectionTables();
120  dxf->writeVPort(*dw);
121 
122  /* Line types */
123 #if (DL_VERSION_MAJOR == 3)
124  dw->tableLinetypes(1);
125  dxf->writeLinetype(*dw, DL_LinetypeData("ByLayer", "ByLayer", 0, 0, 0));
126 #else
127  dw->tableLineTypes(1);
128  dxf->writeLineType(*dw, DL_LineTypeData("ByLayer", 0));
129 #endif
130 
131  dw->tableEnd();
132 
133  /* Layers */
134  dw->tableLayers(1); /* One layer */
135 
136 #if (DL_VERSION_MAJOR == 3)
137  dxf->writeLayer(
138  *dw, DL_LayerData("0", 0),
139  DL_Attributes(
140  "", DL_Codes::black, /* Color */
141  10, /* Width */
142  "Continuous", 1
143  )
144  ); /* Line style and scale */
145 #else
146  dxf->writeLayer(
147  *dw, DL_LayerData("0", 0),
148  DL_Attributes(
149  "", DL_Codes::black, /* Color */
150  10, /* Width */
151  "Continuous"
152  )
153  ); /* Line style */
154 #endif
155 
156  dw->tableEnd();
157 
158 #if (DL_VERSION_MAJOR == 3)
159  dxf->writeStyle(*dw, DL_StyleData("Standard", 0, 2.5, 1.0, 0.0, 0, 2.5, "txt", ""));
160 #else
161  dxf->writeStyle(*dw);
162 #endif
163 
164  dxf->writeView(*dw);
165  dxf->writeUcs(*dw);
166  dw->tableAppid(1);
167  dw->tableAppidEntry(0x12);
168  dw->dxfString(2, "ACAD");
169  dw->dxfInt(DL_ATTFLAGS_CODE, 0);
170  dw->tableEnd();
171  dw->sectionEnd();
172 
173  /* All entities */
174  dw->sectionEntities();
175 
176 #if (DL_VERSION_MAJOR == 3)
177  DL_Attributes* attr = new DL_Attributes("0", 0, -1, "ByLayer", 1.0);
178 #else
179  DL_Attributes* attr = new DL_Attributes("0", 0, -1, "ByLayer");
180 #endif
181 
182  for (net = img->netlist; net != NULL; net = net->next) {
183  apert = img->aperture[net->aperture];
184  if (!apert)
185  continue;
186 
188  dxf->writePolyline(*dw, DL_PolylineData(1, 0, 0, DL_CLOSED_PLINE), *attr);
189 
190  net = net->next;
191 
192  while (net != NULL && net->interpolation != GERBV_INTERPOLATION_PAREA_END) {
194  dxf->writeVertex(*dw, DL_VertexData(COORD2INS(net->stop_x), COORD2INS(net->stop_y), 0, 0));
195  }
196  net = net->next;
197  }
198 
199  dxf->writePolylineEnd(*dw);
200 
201  continue;
202  }
203 
204  switch (net->aperture_state) {
206  switch (apert->type) {
207  case GERBV_APTYPE_CIRCLE:
208  x[0] = net->stop_x;
209  y[0] = net->stop_y;
210  r = apert->parameter[0] / 2;
211  dxf->writeCircle(*dw, DL_CircleData(x[0], y[0], 0.0, r), *attr);
212  break;
214  x[0] = net->stop_x + apert->parameter[0] / 2;
215  y[0] = net->stop_y + apert->parameter[1] / 2;
216  x[1] = x[0];
217  y[1] = y[0] - apert->parameter[1];
218  x[2] = x[1] - apert->parameter[0];
219  y[2] = y[1];
220  x[3] = x[2];
221  y[3] = y[0];
222  dxf->writePolyline(*dw, DL_PolylineData(4, 0, 0, DL_CLOSED_PLINE), *attr);
223  for (i = 0; i < 4; i++)
224  dxf->writeVertex(*dw, DL_VertexData(x[i], y[i], 0, 0));
225  dxf->writePolylineEnd(*dw);
226  break;
227  case GERBV_APTYPE_OVAL:
228  if (apert->parameter[0] > apert->parameter[1]) {
229  /* Horizontal oval */
230  r = apert->parameter[1] / 2;
231  dx = apert->parameter[0] / 2 - r;
232 
233  x[0] = net->stop_x - dx;
234  y[0] = net->stop_y + r;
235  x[1] = net->stop_x + dx;
236  y[1] = y[0];
237  x[2] = x[1];
238  y[2] = net->stop_y - r;
239  x[3] = x[0];
240  y[3] = y[2];
241  } else {
242  /* Vertical oval */
243  r = apert->parameter[0] / 2;
244  dy = apert->parameter[1] / 2 - r;
245 
246  x[0] = net->stop_x - r;
247  y[0] = net->stop_y - dy;
248  x[1] = x[0];
249  y[1] = net->stop_y + dy;
250  x[2] = net->stop_x + r;
251  y[2] = y[1];
252  x[3] = x[2];
253  y[3] = y[0];
254  }
255 
256  dxf->writePolyline(*dw, DL_PolylineData(4, 0, 0, DL_CLOSED_PLINE), *attr);
257  dxf->writeVertex(*dw, DL_VertexData(x[3], y[3], 0, -1));
258  dxf->writeVertex(*dw, DL_VertexData(x[0], y[0], 0, 0));
259  dxf->writeVertex(*dw, DL_VertexData(x[1], y[1], 0, -1));
260  dxf->writeVertex(*dw, DL_VertexData(x[2], y[2], 0, 0));
261 
262  dxf->writePolylineEnd(*dw);
263  break;
264  case GERBV_APTYPE_MACRO:
265  default:
266  /* TODO: other GERBV_APTYPE_ */
267  GERB_COMPILE_WARNING(
268  "%s:%d: aperture type %d is "
269  "not yet supported",
270  __func__, __LINE__, apert->type
271  );
272  break;
273  }
274  break;
276  /* Line or cut slot in drill file */
277  switch (apert->type) {
278  case GERBV_APTYPE_CIRCLE:
279  /* Calculate perpendicular vector */
280  dx = net->stop_x - net->start_x;
281  dy = net->stop_y - net->start_y;
282  nom = apert->parameter[0] / (2 * sqrt(dx * dx + dy * dy));
283  dx = dx * nom;
284  dy = dy * nom;
285 
286  /* Line 1 of 2 */
287  x[0] = net->stop_x + dy;
288  y[0] = net->stop_y - dx;
289  x[1] = net->start_x + dy;
290  y[1] = net->start_y - dx;
291 
292  /* Line 2 of 2 */
293  x[2] = net->start_x - dy;
294  y[2] = net->start_y + dx;
295  x[3] = net->stop_x - dy;
296  y[3] = net->stop_y + dx;
297 
298  dxf->writePolyline(*dw, DL_PolylineData(4, 0, 0, DL_CLOSED_PLINE), *attr);
299  dxf->writeVertex(*dw, DL_VertexData(x[3], y[3], 0, -1));
300  dxf->writeVertex(*dw, DL_VertexData(x[0], y[0], 0, 0));
301  dxf->writeVertex(*dw, DL_VertexData(x[1], y[1], 0, -1));
302  dxf->writeVertex(*dw, DL_VertexData(x[2], y[2], 0, 0));
303 
304  dxf->writePolylineEnd(*dw);
305  break;
306  default:
307  GERB_COMPILE_WARNING(
308  "%s:%d: aperture type %d is "
309  "not yet supported",
310  __func__, __LINE__, apert->type
311  );
312  break;
313  }
314  break;
315  default: break;
316  }
317  }
318 
319  gerbv_destroy_image(img);
320 
321  dw->sectionEnd();
322 
323  dxf->writeObjects(*dw);
324  dxf->writeObjectsEnd(*dw);
325  dw->dxfEOF();
326  dw->close();
327 
328  delete attr;
329  delete dw;
330  delete dxf;
331 
332  setlocale(LC_NUMERIC, ""); /* Return to the default locale */
333 
334  return TRUE;
335 }
336 } /* extern "C" */
Contains basic defines.
gboolean gerbv_export_dxf_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 DXF format.
Definition: export-dxf.cpp:77
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_MACRO
Definition: gerbv.h:156
@ 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
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