#usage "DXF Converter

\n" "Converts a board or schematic into a DXF file.

\n" "DXF syntax generated according to the specifications given in the book
\n" "     Der DXF-Standard
\n" "     By Dietmar Rudolph
\n" "     Publisher: Dr. L. Rossipaul Verlagsgesellschaft m.b.H.
\n" "     München, 1993
\n" "     ISBN 3-87686-246-9

\n" "Author: support@cadsoft.de" // // The following switches allow us to customize the generated DXF file: // enum { NO, YES }; int UseWireWidths = YES; // YES will generate wires, arcs and circles // as polygons showing their real widths. // This, however, can cause the DXF file to // become very large! // Set this to NO if you do not need the real // widths. int FillAreas = YES; // YES will fill wires, arcs etc. You must also // set UseWireWidths to YES for this to work int SafetyOverlap = 1.0 / u2mil(1); // 1.0 mil overlap int PadColor = 0, ViaColor = 0; // // Some tools we need later: // real DxfAngle(real a) { return a >= 360 ? a - 360 : a; // 0 <= DXF-Angle < 360 } int tx2 = 0, ty2 = 0; void GetTextPoint(UL_TEXT T) { int w, ex, ey; ex = tx2 = T.x; ey = ty2 = T.y; T.wires(W) { tx2 = (W.x1 > ex) ? max(W.x1, max(W.x2, tx2)) : min(W.x1, min(W.x2, tx2)); ty2 = (W.y1 > ey) ? max(W.y1, max(W.y2, ty2)) : min(W.y1, min(W.y2, ty2)); w = W.width; } w /= 2; tx2 += (tx2 > ex) ? w : -w; ty2 += (ty2 > ey) ? w : -w; } int LayerActive[] = {1}; // // Level 0: DXF code generating functions: // void DxfString(int code, string value) { printf("%3d\n%s\n", code, value); } void DxfInt(int code, int value) { printf("%3d\n%d\n", code, value); } void DxfReal(int code, real value) { printf("%3d\n%1.3f\n", code, value); } // // Level 1: DXF group functions: // void DxfCoordinate(int n, real x, real y) { DxfReal(10 + n, x); DxfReal(20 + n, y); DxfReal(30 + n, 0.0); } void DxfSection(string name) { DxfString(0, "SECTION"); DxfString(2, name); } void DxfEndSection(void) { DxfString(0, "ENDSEC"); } void DxfTable(string name, int number) { DxfString(0, "TABLE"); DxfString(2, name); DxfInt(70, number); } void DxfEndTable(void) { DxfString(0, "ENDTAB"); } void DxfBlock(string name) { DxfString(0, "BLOCK"); DxfInt(8, 0); DxfString(2, name); DxfInt(70, 64); DxfCoordinate(0, 0.0, 0.0); DxfString(3, name); } void DxfEndBlock(void) { DxfString(0, "ENDBLK"); DxfInt(8, 0); } void DxfVariable(string name) { DxfString(9, "$" + name); } void DxfTrailer(void) { DxfString(0, "EOF"); } void DxfPolyline(int layer, real width) { int Mode = width > 0 ? 0 // polyline is NOT closed : 1; // polyline is closed if (width < 0) width = -width; DxfString(0, "POLYLINE"); DxfInt(8, layer); DxfInt(66, 1); DxfCoordinate(0, 0.0, 0.0); DxfReal(40, width); DxfReal(41, width); DxfInt(70, Mode); } void DxfVertex(int layer, real x, real y) { DxfString(0, "VERTEX"); DxfInt(8, layer); DxfCoordinate(0, x, y); } void DxfVertexRound(int layer, real x, real y, real r) { DxfString(0, "VERTEX"); DxfInt(8, layer); DxfCoordinate(0, x, y); DxfReal(42, r); } void DxfSeqEnd(void) { DxfString(0, "SEQEND"); DxfInt(8, 0); } void DxfInsert(int layer, string name, real x, real y, real dx, real dy) { if (LayerActive[layer]) { DxfString(0, "INSERT"); DxfInt(8, layer); DxfString(2, name); DxfCoordinate(0, x, y); DxfReal(41, dx); DxfReal(42, dy); DxfReal(43, 1.0); } } void DxfPoint(int layer, real x, real y) { if (LayerActive[layer]) { DxfString(0, "POINT"); DxfInt(8, layer); DxfCoordinate(0, x, y); } } void DxfLine(int layer, real x1, real y1, real x2, real y2) { if (LayerActive[layer]) { DxfString(0, "LINE"); DxfInt(8, layer); DxfCoordinate(0, x1, y1); DxfCoordinate(1, x2, y2); } } void DxfCircle(int layer, real x, real y, real r) { if (layer == 0 || LayerActive[layer]) { DxfString(0, "CIRCLE"); DxfInt(8, layer); DxfCoordinate(0, x, y); DxfReal(40, r); } } void DxfArc(int layer, real x, real y, real r, real a1, real a2) { if (LayerActive[layer]) { DxfString(0, "ARC"); DxfInt(8, layer); DxfCoordinate(0, x, y); DxfReal(40, r); DxfReal(50, a1); DxfReal(51, a2); } } void DxfSolid(int layer, real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4) { if (layer == 0 || LayerActive[layer]) { DxfString(0, "SOLID"); DxfInt(8, layer); DxfCoordinate(0, x1, y1); DxfCoordinate(1, x2, y2); DxfCoordinate(2, x3, y3); DxfCoordinate(3, x4, y4); } } void DxfText(int layer, int font, real x, real y, real size, string value, real angle, int mirror) { if (LayerActive[layer]) { DxfString(0, "TEXT"); DxfString(7, font == FONT_PROPORTIONAL ? "ISOCP" : "ISOCT"); DxfInt(8, layer); DxfCoordinate(0, x, y); DxfReal(40, size); DxfString(1, value); if (angle) DxfReal(50, angle); if (mirror) DxfInt(71, 2); } } void DxfLayer(int number, int color) { int Color[] = { 7/*Black*/, 5/*Blue*/, 3/*Green*/, 4/*Cyan*/, 1/*Red*/, 6/*Magenta*/, 9/*Brown*/, 254/*LGray*/, 250/*DGray*/, 10/*LBlue*/, 11/*LGreen*/, 12/*LCyan*/, 13/*LRed*/, 14/*LMagenta*/, 2/*Yellow*/, 7/*White*/}; DxfString(0, "LAYER"); DxfInt(2, number); DxfInt(70, 64); DxfInt(62, Color[color]); DxfString(6, "CONTINUOUS"); } void DxfLineTypes(void) { DxfString(0, "LTYPE"); DxfString(2, "CONTINUOUS"); DxfInt(70, 64); DxfString(3, "Solid line"); DxfInt(72, 65); DxfInt(73, 0); DxfInt(40, 0); } void DxfVersion(void) { DxfVariable("ACADVER"); DxfString(1, "AC1009"); DxfVariable("FILLMODE"); DxfInt(70, FillAreas ? 1 : 0); } // // Level 1: Block definitions for EAGLE primitives: // void DxfOctagonBlock(string name, int layer, real w, real x1, real y1, real x2, real y2) { DxfBlock(name); DxfPolyline(layer, w); DxfVertex(layer, -x1, -y1); DxfVertex(layer, -x1, y1); DxfVertex(layer, -x2, y2); DxfVertex(layer, x2, y2); DxfVertex(layer, x1, y1); DxfVertex(layer, x1, -y1); DxfVertex(layer, x2, -y2); DxfVertex(layer, -x2, -y2); if (FillAreas) { DxfVertex(layer, -x1, -y1); DxfVertex(layer, -x1, y1); } DxfSeqEnd(); DxfEndBlock(); } void DxfBoardBlocks(void) { real f = 1.0 / ((sqrt(2) + 1) * 2); real x = 0.5; real y = f; real w = FillAreas ? 0.5 : 0; real d = FillAreas ? 0.5 : 1; real x1 = 2 * x - w / 2; real y1 = y - w / 4 / sqrt(2); real x2 = 2 * x - (x - (y - w / 4 / sqrt(2))); real y2 = x - w / 2; string pv[] = { "P", "V" }; DxfOctagonBlock("XLONGOCT", 0, w, x1, y1, x2, y2); DxfOctagonBlock("YLONGOCT", 0, w, y2, x2, y1, x1); for (int i = 0; i < 2; ++i) { DxfOctagonBlock("OCTAGON" + pv[i], 0, w, x * d, y * d, y * d, x * d); DxfBlock("SQUARE" + pv[i]); DxfSolid(0, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5); DxfEndBlock(); DxfBlock("ROUND" + pv[i]); if (FillAreas) { DxfPolyline(0, 0.5); DxfVertexRound(0, 0, -0.25, 1); DxfVertexRound(0, 0, 0.25, 1); DxfVertex(0, 0, -0.25); DxfSeqEnd(); } else DxfCircle(0, 0, 0, 0.5); DxfEndBlock(); } } // // Level 2: Low level EAGLE to DXF conversion functions: // void Layer(UL_LAYER L) { if (L.visible) DxfLayer(L.number, L.color); LayerActive[L.number] = L.visible; switch (L.number) { case LAYER_PADS: PadColor = L.color; break; case LAYER_VIAS: ViaColor = L.color; break; } } void Area(UL_AREA A) { DxfVariable("EXTMIN"); DxfCoordinate(0, u2mm(A.x1), u2mm(A.y1)); DxfVariable("EXTMAX"); DxfCoordinate(0, u2mm(A.x2), u2mm(A.y2)); } void Line(UL_WIRE W) { if (UseWireWidths && W.width > 0) { real dx = u2mm(W.x2 - W.x1); real dy = u2mm(W.y2 - W.y1); real l = sqrt(dx * dx + dy * dy); if (l > 0) { if (FillAreas) l *= 2; real w2 = u2mm(W.width / 2); real dxl = dx / l; real dyl = dy / l; real x1 = u2mm(W.x1) + dyl * w2; real y1 = u2mm(W.y1) - dxl * w2; real x2 = u2mm(W.x2) + dyl * w2; real y2 = u2mm(W.y2) - dxl * w2; real x3 = u2mm(W.x2) - dyl * w2; real y3 = u2mm(W.y2) + dxl * w2; real x4 = u2mm(W.x1) - dyl * w2; real y4 = u2mm(W.y1) + dxl * w2; if (FillAreas) { DxfPolyline(W.layer, u2mm(W.width)); DxfVertex(W.layer, u2mm(W.x1), u2mm(W.y1)); DxfVertex(W.layer, u2mm(W.x2), u2mm(W.y2)); DxfSeqEnd(); DxfPolyline(W.layer, u2mm(W.width) / 2); DxfVertexRound(W.layer, x2, y2, 1); DxfVertex(W.layer, x3, y3); DxfSeqEnd(); DxfPolyline(W.layer, u2mm(W.width) / 2); DxfVertexRound(W.layer, x4, y4, 1); DxfVertex(W.layer, x1, y1); DxfSeqEnd(); } else { DxfPolyline(W.layer, 0); DxfVertex(W.layer, x1, y1); DxfVertexRound(W.layer, x2, y2, 1); DxfVertex(W.layer, x3, y3); DxfVertexRound(W.layer, x4, y4, 1); DxfSeqEnd(); } } } else DxfLine(W.layer, u2mm(W.x1), u2mm(W.y1), u2mm(W.x2), u2mm(W.y2)); } void Wire(UL_WIRE W) { if (LayerActive[W.layer]) { if (W.style != WIRE_STYLE_CONTINUOUS) W.pieces(P) Line(P); else Line(W); } } void Circle(UL_CIRCLE C) { if (LayerActive[C.layer]) { if (UseWireWidths) { if (C.width > 0) { if (FillAreas) { DxfPolyline(C.layer, u2mm(C.width)); DxfVertexRound(C.layer, u2mm(C.x), u2mm(C.y - C.radius), 1); DxfVertexRound(C.layer, u2mm(C.x), u2mm(C.y + C.radius), 1); DxfVertex(C.layer, u2mm(C.x), u2mm(C.y - C.radius)); DxfSeqEnd(); } else { int r1 = C.radius - C.width / 2, r2 = C.radius + C.width / 2; if (r1 > 0) DxfCircle(C.layer, u2mm(C.x), u2mm(C.y), u2mm(r1)); DxfCircle(C.layer, u2mm(C.x), u2mm(C.y), u2mm(r2)); } return; } else if (FillAreas) { DxfPolyline(C.layer, u2mm(C.radius)); DxfVertexRound(C.layer, u2mm(C.x), u2mm(C.y - C.radius / 2), 1); DxfVertexRound(C.layer, u2mm(C.x), u2mm(C.y + C.radius / 2), 1); DxfVertex(C.layer, u2mm(C.x), u2mm(C.y - C.radius / 2)); DxfSeqEnd(); return; } } DxfCircle(C.layer, u2mm(C.x), u2mm(C.y), u2mm(C.radius)); } } void Arc(UL_ARC A) { if (LayerActive[A.layer]) { if (UseWireWidths && A.width > 0) { real a1 = A.angle1 / 180 * PI; real a2 = A.angle2 / 180 * PI; real ra = tan((A.angle2 - A.angle1) / 180 * PI / 4); if (FillAreas) { DxfPolyline(A.layer, u2mm(A.width)); DxfVertexRound(A.layer, u2mm(A.x1), u2mm(A.y1), ra); DxfVertex(A.layer, u2mm(A.x2), u2mm(A.y2)); DxfSeqEnd(); } else { real w2 = u2mm(A.width / 2); real x1 = u2mm(A.x1) - w2 * cos(a1); real y1 = u2mm(A.y1) - w2 * sin(a1); real x2 = u2mm(A.x1) + w2 * cos(a1); real y2 = u2mm(A.y1) + w2 * sin(a1); real x3 = u2mm(A.x2) + w2 * cos(a2); real y3 = u2mm(A.y2) + w2 * sin(a2); real x4 = u2mm(A.x2) - w2 * cos(a2); real y4 = u2mm(A.y2) - w2 * sin(a2); DxfPolyline(A.layer, 0); DxfVertex(A.layer, x1, y1); DxfVertexRound(A.layer, x2, y2, ra); DxfVertex(A.layer, x3, y3); DxfVertexRound(A.layer, x4, y4, -ra); DxfSeqEnd(); } } else DxfArc(A.layer, u2mm(A.xc), u2mm(A.yc), u2mm(A.radius), DxfAngle(A.angle1), DxfAngle(A.angle2)); } } void Rectangle(UL_RECTANGLE R) { DxfSolid(R.layer, u2mm(R.x1), u2mm(R.y1), u2mm(R.x2), u2mm(R.y1), u2mm(R.x1), u2mm(R.y2), u2mm(R.x2), u2mm(R.y2)); } void Hole(UL_HOLE H) { DxfCircle(LAYER_DIMENSION, u2mm(H.x), u2mm(H.y), u2mm(H.drill / 2)); } void Via(UL_VIA V) { string Shape[] = { "SQUAREV", "ROUNDV", "OCTAGONV" }; int Count = 0; int Extended = 0; for (int l = LAYER_TOP; l; ) { if (LayerActive[l] || l == Extended) { Count++; DxfInsert(ViaColor ? LAYER_VIAS : l, Shape[V.shape[l]], u2mm(V.x), u2mm(V.y), u2mm(V.diameter[l]), u2mm(V.diameter[l])); } if (l < LAYER_BOTTOM) { if (Extended) l = Extended = LAYER_BOTTOM; else ++l; } else switch (l) { case LAYER_BOTTOM: if (!Extended && !Count && ViaColor && LayerActive[LAYER_VIAS]) l = Extended = LAYER_TOP; else l = LAYER_TSTOP; break; case LAYER_TSTOP: l = LAYER_BSTOP; break; default: l = 0; } } if (Count) DxfCircle(LAYER_DRILLS, u2mm(V.x), u2mm(V.y), u2mm(V.drill / 2)); } void Pad(UL_PAD P) { string Shape[] = { "SQUAREP", "ROUNDP", "OCTAGONP", "XLONGOCT", "YLONGOCT" }; int Count = 0; int Extended = 0; for (int l = LAYER_TOP; l; ) { if (LayerActive[l] || l == Extended) { Count++; DxfInsert(PadColor ? LAYER_PADS : l, Shape[P.shape[l]], u2mm(P.x), u2mm(P.y), u2mm(P.diameter[l]), u2mm(P.diameter[l])); } if (l < LAYER_BOTTOM) { if (Extended) l = Extended = LAYER_BOTTOM; else ++l; } else switch (l) { case LAYER_BOTTOM: if (!Extended && !Count && PadColor && LayerActive[LAYER_PADS]) l = Extended = LAYER_TOP; else l = LAYER_TSTOP; break; case LAYER_TSTOP: l = LAYER_BSTOP; break; default: l = 0; } } if (Count) DxfCircle(LAYER_DRILLS, u2mm(P.x), u2mm(P.y), u2mm(P.drill / 2)); } void Smd(UL_SMD S) { for (int l = S.layer; ; ) { if (LayerActive[l]) { int dx2 = S.dx[l] / 2, dy2 = S.dy[l] / 2; int DrawBar = 0; if (FillAreas && S.roundness == 100 && dx2 == dy2) { DxfPolyline(l, -u2mm(dy2)); DxfVertexRound(l, u2mm(S.x), u2mm(S.y - dy2 / 2), 1); DxfVertexRound(l, u2mm(S.x), u2mm(S.y + dy2 / 2), 1); DxfSeqEnd(); } else if (S.roundness) { real rr = sqrt(2) - 1; int rf = min(dx2, dy2) * S.roundness / 100; if (FillAreas) { rf /= 2; dx2 -= rf; dy2 -= rf; } real r = u2mm(rf); real x1 = u2mm(S.x - dx2), y1 = u2mm(S.y - dy2), x2 = u2mm(S.x + dx2), y2 = u2mm(S.y + dy2); DxfPolyline(l, FillAreas ? -2 * r : 0); DxfVertex (l, x2 , y1 + r); DxfVertexRound(l, x2 , y2 - r, rr); DxfVertex (l, x2 - r, y2 ); DxfVertexRound(l, x1 + r, y2 , rr); DxfVertex (l, x1 , y2 - r); DxfVertexRound(l, x1 , y1 + r, rr); DxfVertex (l, x1 + r, y1 ); DxfVertexRound(l, x2 - r, y1 , rr); DxfSeqEnd(); if (FillAreas) { int o = min(SafetyOverlap, rf / 2); dx2 -= rf - o; dy2 -= rf - o; DrawBar = 1; } } else DrawBar = 1; if (DrawBar) DxfSolid(l, u2mm(S.x - dx2), u2mm(S.y - dy2), u2mm(S.x + dx2), u2mm(S.y - dy2), u2mm(S.x - dx2), u2mm(S.y + dy2), u2mm(S.x + dx2), u2mm(S.y + dy2)); } switch (l) { case LAYER_TOP: l = LAYER_TSTOP; break; case LAYER_TSTOP: l = LAYER_TCREAM; break; case LAYER_BOTTOM: l = LAYER_BSTOP; break; case LAYER_BSTOP: l = LAYER_BCREAM; break; default: return; } } } void Junction(UL_JUNCTION J) { if (FillAreas) { DxfPolyline(LAYER_NETS, u2mm(J.diameter / 2)); DxfVertexRound(LAYER_NETS, u2mm(J.x), u2mm(J.y - J.diameter / 4), 1); DxfVertexRound(LAYER_NETS, u2mm(J.x), u2mm(J.y + J.diameter / 4), 1); DxfVertex(LAYER_NETS, u2mm(J.x), u2mm(J.y - J.diameter / 4)); DxfSeqEnd(); } else DxfCircle(LAYER_NETS, u2mm(J.x), u2mm(J.y), u2mm(J.diameter / 2)); } void Polygon(UL_POLYGON P) { P.contours(W) Wire(W); if (P.width > 0) P.fillings(W) Wire(W); else if (dlgMessageBox("Can't fill polygon with Width = 0", "+Ok", "-Cancel") != 0) exit(1); } void Text(UL_TEXT T) { if (LayerActive[T.layer]) { if (T.font == FONT_VECTOR) { T.wires(W) Line(W); } else { // Although DXF offers several parameters to fine tune a text, most // DXF aware programs do not process these parameters correctly. // Therefore we make a very basic approach here. int x = T.x; int y = T.y; int angle = T.angle; // makes it int for easier processing! if (T.mirror) { switch (angle) { case 0: case 90: if (!board) { GetTextPoint(T); x = tx2; } break; case 180: case 270: GetTextPoint(T); if (board) x = tx2; y = ty2; break; } } else { switch (angle) { case 180: case 270: GetTextPoint(T); x = tx2; y = ty2; break; } } if (sheet || !T.mirror) angle = (angle == 90 || angle == 270) ? 90 : 0; else if (T.mirror) angle = (angle == 90 || angle == 270) ? 270 : 0; DxfText(T.layer, T.font, u2mm(x), u2mm(y), u2mm(T.size), T.value, angle, board ? T.mirror : 0); } } } // // Level 3: High level EAGLE decomposing functions: // void Package(UL_PACKAGE P) { P.polygons(P) Polygon(P); P.wires(W) Wire(W); P.texts(T) Text(T); P.arcs(A) Arc(A); P.circles(C) Circle(C); P.rectangles(R) Rectangle(R); P.holes(H) Hole(H); P.contacts(C) { if (C.pad) Pad(C.pad); else Smd(C.smd); } } void Element(UL_ELEMENT E) { int layer; switch (E.mirror) { case 0: layer = LAYER_TORIGINS; break; // not mirrored case 1: layer = LAYER_BORIGINS; break; // mirrored } DxfPoint(layer, u2mm(E.x), u2mm(E.y)); Package(E.package); E.texts(T) Text(T); } void Signal(UL_SIGNAL S) { S.polygons(P) Polygon(P); S.wires(W) Wire(W); S.vias(V) Via(V); } void Board(UL_BOARD B) { B.polygons(P) Polygon(P); B.wires(W) Wire(W); B.texts(T) Text(T); B.arcs(A) Arc(A); B.circles(C) Circle(C); B.rectangles(R) Rectangle(R); B.holes(H) Hole(H); B.elements(E) Element(E); B.signals(S) Signal(S); } void Pin(UL_PIN P) { P.wires(W) Wire(W); P.circles(C) Circle(C); P.texts(T) Text(T); } void Symbol(UL_SYMBOL S) { S.polygons(P) Polygon(P); S.wires(W) Wire(W); S.texts(T) Text(T); S.pins(P) Pin(P); S.arcs(A) Arc(A); S.circles(C) Circle(C); S.rectangles(R) Rectangle(R); } void Instance(UL_INSTANCE I) { Symbol(I.gate.symbol); I.texts(T) Text(T); } void Part(UL_PART P) { P.instances(I) Instance(I); } void Segment(UL_SEGMENT S) { S.wires(W) Wire(W); S.junctions(J) Junction(J); S.texts(T) Text(T); } void Bus(UL_BUS B) { B.segments(S) Segment(S); } void Net(UL_NET N) { N.segments(S) Segment(S); } void Sheet(UL_SHEET S) { S.polygons(P) Polygon(P); S.wires(W) Wire(W); S.texts(T) Text(T); S.arcs(A) Arc(A); S.circles(C) Circle(C); S.rectangles(R) Rectangle(R); S.parts(P) Part(P); S.busses(B) Bus(B); S.nets(N) Net(N); } // // Main program: // string OutputFileName; if (board) board(B) OutputFileName = B.name; else if (schematic) schematic(SCH) OutputFileName = SCH.name; else { dlgMessageBox(usage + "


ERROR: No board or schematic!

\nThis program can only work in the board or schematic editor."); exit(1); } OutputFileName = filesetext(OutputFileName, ".dxf"); dlgDialog("DXF Converter") { dlgHBoxLayout { dlgLabel("&Output file"); dlgStringEdit(OutputFileName); dlgPushButton("&Browse") { string FileName = dlgFileSave("Save DXF file", OutputFileName, "DXF files (*.dxf)"); if (FileName) OutputFileName = FileName; } } dlgCheckBox("&Use wire widths", UseWireWidths) { UseWireWidths |= FillAreas; }; dlgLabel("If checked, wires, arcs and circles will be generated as polygons showing their real widths." "This, however, can cause the DXF file to become very large!" "Uncheck this if you do not need the real widths."); dlgCheckBox("&Fill areas", FillAreas) { UseWireWidths |= FillAreas; } dlgLabel("If checked, wires, arcs etc. will be filled (implies 'Use wire widths'!)."); dlgStretch(1); dlgHBoxLayout { dlgStretch(1); dlgPushButton("+Ok") { string a[]; if (!fileglob(a, OutputFileName) || dlgMessageBox("File '" + OutputFileName + "' exists\n\nOverwrite?", "+&Yes", "-&No") == 0) dlgAccept(); } dlgPushButton("-Cancel") { dlgReject(); exit(1); } dlgPushButton("About") dlgMessageBox(usage); } }; output(OutputFileName) { DxfSection("HEADER"); DxfVersion(); if (board) board(B) Area(B.area); else sheet(S) Area(S.area); DxfEndSection(); DxfSection("TABLES"); DxfTable("LTYPE", 1); DxfLineTypes(); DxfEndTable(); DxfTable("LAYER", 255); if (board) board(B) B.layers(L) Layer(L); else schematic(SCH) SCH.layers(L) Layer(L); DxfEndTable(); DxfEndSection(); if (board) { DxfSection("BLOCKS"); DxfBoardBlocks(); DxfEndSection(); } DxfSection("ENTITIES"); if (board) board(B) Board(B); else sheet(S) Sheet(S); DxfEndSection(); DxfTrailer(); }