gerbv
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 <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 {
77 gboolean
78 gerbv_export_dxf_file_from_image(const gchar *file_name,
79  gerbv_image_t *input_img,
81 {
82  DL_Codes::version exportVersion = DL_Codes::AC1015;
83  DL_Dxf* dxf = new DL_Dxf();
84  DL_WriterA* dw;
85  gerbv_aperture_t *apert;
86  gerbv_image_t *img;
87  gerbv_net_t *net;
88  double x[4], y[4], r, dx, dy, nom;
89  unsigned int i;
90 
91  dw = dxf->out(file_name, exportVersion);
92 
93  if (dw == NULL) {
94  GERB_MESSAGE(_("Can't open file for writing: %s"), file_name);
95  return FALSE;
96  }
97 
98  /* Output decimals as dots for all locales */
99  setlocale(LC_NUMERIC, "C");
100 
101  /* Duplicate the image, cleaning it in the process */
102  img = gerbv_image_duplicate_image(input_img, trans);
103 
104  dxf->writeHeader(*dw);
105 
106  dw->dxfString(DL_STRGRP_END, "$INSUNITS");
107  dw->dxfInt(DL_ATTFLAGS_CODE, INSUNITS_INCH);
108 
109  dw->dxfString(DL_STRGRP_END, "$DIMEXE");
110  dw->dxfReal(DL_TXTHI_CODE, 1.25);
111 
112  dw->dxfString(DL_STRGRP_END, "$TEXTSTYLE");
113  dw->dxfString(DL_TXT_STYLE_CODE, "Standard");
114 
115  /* TODO ? */
116  dw->dxfString(DL_STRGRP_END, "$LIMMIN");
117  dw->dxfReal(DL_FIRST_XCOORD_CODE, 0.0);
118  dw->dxfReal(DL_FIRST_YCOORD_CODE, 0.0);
119 
120  dw->sectionEnd();
121 
122  dw->sectionTables();
123  dxf->writeVPort(*dw);
124 
125  /* Line types */
126 #if (DL_VERSION_MAJOR == 3)
127  dw->tableLinetypes(1);
128  dxf->writeLinetype(*dw, DL_LinetypeData("ByLayer", "ByLayer", 0, 0, 0));
129 #else
130  dw->tableLineTypes(1);
131  dxf->writeLineType(*dw, DL_LineTypeData("ByLayer", 0));
132 #endif
133 
134  dw->tableEnd();
135 
136  /* Layers */
137  dw->tableLayers(1); /* One layer */
138 
139 #if (DL_VERSION_MAJOR == 3)
140  dxf->writeLayer(*dw, DL_LayerData("0", 0),
141  DL_Attributes("",
142  DL_Codes::black,/* Color */
143  10, /* Width */
144  "Continuous", 1)); /* Line style and scale */
145 #else
146  dxf->writeLayer(*dw, DL_LayerData("0", 0),
147  DL_Attributes("",
148  DL_Codes::black,/* Color */
149  10, /* Width */
150  "Continuous")); /* Line style */
151 #endif
152 
153  dw->tableEnd();
154 
155 #if (DL_VERSION_MAJOR == 3)
156  dxf->writeStyle(*dw, DL_StyleData("Standard",
157  0, 2.5, 1.0, 0.0, 0, 2.5, "txt", ""));
158 #else
159  dxf->writeStyle(*dw);
160 #endif
161 
162  dxf->writeView(*dw);
163  dxf->writeUcs(*dw);
164  dw->tableAppid(1);
165  dw->tableAppidEntry(0x12);
166  dw->dxfString(2, "ACAD");
167  dw->dxfInt(DL_ATTFLAGS_CODE, 0);
168  dw->tableEnd();
169  dw->sectionEnd();
170 
171  /* All entities */
172  dw->sectionEntities();
173 
174 #if (DL_VERSION_MAJOR == 3)
175  DL_Attributes *attr = new DL_Attributes("0", 0, -1, "ByLayer", 1.0);
176 #else
177  DL_Attributes *attr = new DL_Attributes("0", 0, -1, "ByLayer");
178 #endif
179 
180  for (net = img->netlist; net != NULL; net = net->next) {
181  apert = img->aperture[net->aperture];
182  if (!apert)
183  continue;
184 
186  dxf->writePolyline(*dw,
187  DL_PolylineData(1, 0, 0, DL_CLOSED_PLINE),
188  *attr);
189 
190  net = net->next;
191 
192  while (net != NULL && net->interpolation !=
194  if (net->aperture_state ==
198  net->cirseg) {
199  double a1 = DEG2RAD(net->cirseg->angle1);
200  double a2 = DEG2RAD(net->cirseg->angle2);
201  double ar = net->cirseg->width / 2.0;
202  double cx = net->cirseg->cp_x;
203  double cy = net->cirseg->cp_y;
204  int steps = (int)(fabs(net->cirseg->angle2 -
205  net->cirseg->angle1) / 2.0) + 1;
206  for (int s = 1; s <= steps; s++) {
207  double a = a1 + (a2 - a1) * s / steps;
208  dxf->writeVertex(*dw,
209  DL_VertexData(
210  cx + ar * cos(a),
211  cy + ar * sin(a),
212  0, 0));
213  }
214  } else {
215  dxf->writeVertex(*dw,
216  DL_VertexData(
217  COORD2INS(net->stop_x),
218  COORD2INS(net->stop_y),
219  0, 0));
220  }
221  }
222  net = net->next;
223  }
224 
225  dxf->writePolylineEnd(*dw);
226 
227  continue;
228  }
229 
230  switch (net->aperture_state) {
232  switch (apert->type) {
233  case GERBV_APTYPE_CIRCLE:
234  x[0] = net->stop_x;
235  y[0] = net->stop_y;
236  r = apert->parameter[0]/2;
237  dxf->writeCircle(*dw,
238  DL_CircleData(x[0], y[0], 0.0, r),
239  *attr);
240  break;
242  x[0] = net->stop_x + apert->parameter[0]/2;
243  y[0] = net->stop_y + apert->parameter[1]/2;
244  x[1] = x[0];
245  y[1] = y[0] - apert->parameter[1];
246  x[2] = x[1] - apert->parameter[0];
247  y[2] = y[1];
248  x[3] = x[2];
249  y[3] = y[0];
250  dxf->writePolyline(*dw,
251  DL_PolylineData(4, 0, 0, DL_CLOSED_PLINE),
252  *attr);
253  for (i = 0; i < 4; i++)
254  dxf->writeVertex(*dw,
255  DL_VertexData(x[i], y[i], 0, 0));
256  dxf->writePolylineEnd(*dw);
257  break;
258  case GERBV_APTYPE_OVAL:
259  if (apert->parameter[0] > apert->parameter[1]) {
260  /* Horizontal oval */
261  r = apert->parameter[1]/2;
262  dx = apert->parameter[0]/2 - r;
263 
264  x[0] = net->stop_x - dx;
265  y[0] = net->stop_y + r;
266  x[1] = net->stop_x + dx;
267  y[1] = y[0];
268  x[2] = x[1];
269  y[2] = net->stop_y - r;
270  x[3] = x[0];
271  y[3] = y[2];
272  } else {
273  /* Vertical oval */
274  r = apert->parameter[0]/2;
275  dy = apert->parameter[1]/2 - r;
276 
277  x[0] = net->stop_x - r;
278  y[0] = net->stop_y - dy;
279  x[1] = x[0];
280  y[1] = net->stop_y + dy;
281  x[2] = net->stop_x + r;
282  y[2] = y[1];
283  x[3] = x[2];
284  y[3] = y[0];
285  }
286 
287  dxf->writePolyline(*dw,
288  DL_PolylineData(4, 0, 0, DL_CLOSED_PLINE),
289  *attr);
290  dxf->writeVertex(*dw,
291  DL_VertexData(x[3], y[3], 0, -1));
292  dxf->writeVertex(*dw,
293  DL_VertexData(x[0], y[0], 0, 0));
294  dxf->writeVertex(*dw,
295  DL_VertexData(x[1], y[1], 0, -1));
296  dxf->writeVertex(*dw,
297  DL_VertexData(x[2], y[2], 0, 0));
298 
299  dxf->writePolylineEnd(*dw);
300  break;
301  case GERBV_APTYPE_MACRO:
302  default:
303 /* TODO: other GERBV_APTYPE_ */
304  GERB_COMPILE_WARNING(
305  "%s:%d: aperture type %d is "
306  "not yet supported",
307  __func__, __LINE__,
308  apert->type);
309  break;
310  }
311  break;
315  net->cirseg) {
316  double a1 = net->cirseg->angle1;
317  double a2 = net->cirseg->angle2;
319  double tmp = a1;
320  a1 = a2;
321  a2 = tmp;
322  }
323  dxf->writeArc(*dw,
324  DL_ArcData(net->cirseg->cp_x,
325  net->cirseg->cp_y, 0.0,
326  net->cirseg->width / 2.0,
327  a1, a2),
328  *attr);
329  break;
330  }
331  /* Line or cut slot in drill file */
332  switch (apert->type) {
333  case GERBV_APTYPE_CIRCLE:
334  /* Calculate perpendicular vector */
335  dx = net->stop_x - net->start_x;
336  dy = net->stop_y - net->start_y;
337  nom = apert->parameter[0] /
338  (2*sqrt(dx*dx + dy*dy));
339  dx = dx * nom;
340  dy = dy * nom;
341 
342  /* Line 1 of 2 */
343  x[0] = net->stop_x + dy;
344  y[0] = net->stop_y - dx;
345  x[1] = net->start_x + dy;
346  y[1] = net->start_y - dx;
347 
348  /* Line 2 of 2 */
349  x[2] = net->start_x - dy;
350  y[2] = net->start_y + dx;
351  x[3] = net->stop_x - dy;
352  y[3] = net->stop_y + dx;
353 
354  dxf->writePolyline(*dw,
355  DL_PolylineData(4, 0, 0, DL_CLOSED_PLINE),
356  *attr);
357  dxf->writeVertex(*dw,
358  DL_VertexData(x[3], y[3], 0, -1));
359  dxf->writeVertex(*dw,
360  DL_VertexData(x[0], y[0], 0, 0));
361  dxf->writeVertex(*dw,
362  DL_VertexData(x[1], y[1], 0, -1));
363  dxf->writeVertex(*dw,
364  DL_VertexData(x[2], y[2], 0, 0));
365 
366  dxf->writePolylineEnd(*dw);
367  break;
368  default:
369  GERB_COMPILE_WARNING(
370  "%s:%d: aperture type %d is "
371  "not yet supported",
372  __func__, __LINE__,
373  apert->type);
374  break;
375  }
376  break;
377  default:
378  break;
379  }
380 
381  }
382 
383  gerbv_destroy_image(img);
384 
385  dw->sectionEnd();
386 
387  dxf->writeObjects(*dw);
388  dxf->writeObjectsEnd(*dw);
389  dw->dxfEOF();
390  dw->close();
391 
392  delete attr;
393  delete dw;
394  delete dxf;
395 
396  setlocale(LC_NUMERIC, ""); /* Return to the default locale */
397 
398  return TRUE;
399 }
400 } /* extern "C" */
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:78
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_MACRO
Definition: gerbv.h:164
@ GERBV_APTYPE_CIRCLE
Definition: gerbv.h:160
@ GERBV_APTYPE_RECTANGLE
Definition: gerbv.h:161
@ GERBV_INTERPOLATION_PAREA_START
Definition: gerbv.h:308
@ GERBV_INTERPOLATION_CW_CIRCULAR
Definition: gerbv.h:306
@ GERBV_INTERPOLATION_PAREA_END
Definition: gerbv.h:309
@ GERBV_INTERPOLATION_CCW_CIRCULAR
Definition: gerbv.h:307
gerbv_net_t * netlist
Definition: gerbv.h:729
gerbv_aperture_t * aperture[APERTURE_MAX]
Definition: gerbv.h:723
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
gerbv_cirseg_t * cirseg
Definition: gerbv.h:665
int aperture
Definition: gerbv.h:662