Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
286 lines (262 sloc) 7.26 KB
//
// Export the EAGLE cream layers to DXF for the Craft-ROBO cutting plotter.
//
// Copyright (c) 2010 SWITCHSCIENCE, Inc.
// Copyright (c) 2012 Yoshihiro TSUBOI
// Copyright (c) 2013 Yuuki Uno, NYAMFG.
// Copyright (c) 2015 Junichi Akita (akita11), added board outline cut
// Configuration
real SHRINK_WIDTH = 0.00; // unit: mm
real MIN_CORNERRADIUS = 0.05; // unit: mm
real E6_SCALE = 32; // The internal resolution of EAGLE 6 has been increased by a factor of 32. For detail, see UPDATE_en.txt
// Flags
int CORNERCUT = 0; // boolean
int CUTTIMES = 1;
int EAGLE6 = 0;
int IGNORESTOP = 1;
int OUTLINE = 0;
string HEADER =
" 0\n"
"SECTION\n"
" 2\n"
"HEADER\n"
" 9\n"
"$ACADVER\n"
" 1\n"
"AC1009\n"
" 9\n"
"$MEASUREMENT\n"
" 70\n"
" 1\n" // unit: mm
" 0\n"
"ENDSEC\n"
" 0\n"
"SECTION\n"
" 2\n"
"ENTITIES\n";
string POLYLINE =
" 0\n"
"LWPOLYLINE\n"
" 8\n"
"0\n" // layer
" 62\n"
"7\n" // color
" 90\n"
"%d\n" // number of points
" 70\n"
"%d\n"; // 0=open 1=close
string POLYLINE_POINT =
" 10\n"
"%f\n"
" 20\n"
"%f\n";
string LINE =
" 0\n"
"LINE\n"
" 8\n"
"0\n" // layer
" 10\n"
"%f\n" // start x
" 20\n"
"%f\n" // start y
" 11\n"
"%f\n" // end x
" 21\n"
"%f\n"; // end y
string ARC =
" 0\n"
"ARC\n"
" 8\n"
"0\n" // layer
" 10\n"
"%f\n" // center x
" 20\n"
"%f\n" // center y
" 40\n"
"%f\n" // radius
" 50\n"
"%f\n" // start angle
" 51"
"%f\n"; // end angle
string CIRCLE =
" 0\n"
"CIRCLE\n"
" 8\n"
"0\n" // layer
" 10\n"
"%f\n" // center x
" 20\n"
"%f\n" // center y
" 40\n"
"%f\n"; // radius
string TRAILER =
" 0\n"
"ENDSEC\n"
" 0\n"
"EOF\n";
int
processLayer(UL_BOARD B, int layer) {
int count = 0;
int cream = (layer == LAYER_TOP ? LAYER_TCREAM : LAYER_BCREAM);
printf("%s", HEADER);
B.elements(E) {
E.package.contacts(C) {
if (!C.smd)
continue;
if (C.smd.layer != layer)
continue;
if (!((C.smd.flags & SMD_FLAG_STOP) || !IGNORESTOP))
continue;
if (!(C.smd.flags & SMD_FLAG_CREAM))
continue;
if (C.smd.dx[cream] == 0 || C.smd.dy[cream] == 0)
continue;
real x = C.smd.x / 10000.0;
real y = C.smd.y / 10000.0;
real w = C.smd.dx[cream] / 10000.0 / 2 - SHRINK_WIDTH;
real h = C.smd.dy[cream] / 10000.0 / 2 - SHRINK_WIDTH;
if (EAGLE6 == 1) {
x = x / E6_SCALE;
y = y / E6_SCALE;
w = w / E6_SCALE;
h = h / E6_SCALE;
}
real a = C.smd.angle / 180 * PI;
real wc = w * cos(a);
real hs = h * sin(a);
real ws = w * sin(a);
real hc = h * cos(a);
real r = max(min(w, h) * C.smd.roundness / 100, MIN_CORNERRADIUS);
if (CORNERCUT && h > r && w > r) {
real rc = r * cos(a);
real rs = r * sin(a);
printf(POLYLINE, 8 * CUTTIMES + 1, 1); // 1: closed
printf(POLYLINE_POINT, x + wc, y + ws); // ( w, 0)
for (int i = 0; i < CUTTIMES; i++) {
printf(POLYLINE_POINT, x + wc - hs + rs, y + ws + hc - rc); // ( w, h-r)
printf(POLYLINE_POINT, x + wc - rc - hs, y + ws - rs + hc); // ( w-r, h)
printf(POLYLINE_POINT, x - wc + rc - hs, y - ws + rs + hc); // (-w+r, h)
printf(POLYLINE_POINT, x - wc - hs + rs, y - ws + hc - rc); // (-w, h-r)
printf(POLYLINE_POINT, x - wc + hs - rs, y - ws - hc + rc); // (-w, -h+r)
printf(POLYLINE_POINT, x - wc + rc + hs, y - ws + rs - hc); // (-w+r, -h)
printf(POLYLINE_POINT, x + wc - rc + hs, y + ws - rs - hc); // ( w-r, -h)
printf(POLYLINE_POINT, x + wc + hs - rs, y + ws - hc + rc); // ( w, -h+r)
}
} else {
printf(POLYLINE, 4 * CUTTIMES + 1, 1); // 1: closed
printf(POLYLINE_POINT, x + wc, y + ws); // ( w, 0)
for (int i = 0; i < CUTTIMES; i++) {
printf(POLYLINE_POINT, x + wc - hs, y + ws + hc); // ( w, h)
printf(POLYLINE_POINT, x - wc - hs, y - ws + hc); // (-w, h)
printf(POLYLINE_POINT, x - wc + hs, y - ws - hc); // (-w, -h)
printf(POLYLINE_POINT, x + wc + hs, y + ws - hc); // ( w, -h)
}
}
count++;
}
E.package.rectangles(R) {
if (layer==LAYER_TOP && R.layer == 31) {
printf(POLYLINE, 4 * CUTTIMES + 1, 1); // 1: closed
real x = (R.x1+R.x2)/2 / 10000.0;
real y = (R.y1+R.y2)/2 / 10000.0;
real w = (R.x2-R.x1) / 10000.0 / 2 - SHRINK_WIDTH;
real h = (R.y2-R.y1) / 10000.0 / 2 - SHRINK_WIDTH;
if (EAGLE6 == 1) {
x = x / E6_SCALE;
y = y / E6_SCALE;
w = w / E6_SCALE;
h = h / E6_SCALE;
}
real a = R.angle / 180 * PI;
real wc = w * cos(a);
real hs = h * sin(a);
real ws = w * sin(a);
real hc = h * cos(a);
printf(POLYLINE, 4 * CUTTIMES + 1, 1); // 1: closed
printf(POLYLINE_POINT, x + wc, y + ws); // ( w, 0)
for (int i = 0; i < CUTTIMES; i++) {
printf(POLYLINE_POINT, x + wc - hs, y + ws + hc); // ( w, h)
printf(POLYLINE_POINT, x - wc - hs, y - ws + hc); // (-w, h)
printf(POLYLINE_POINT, x - wc + hs, y - ws - hc); // (-w, -h)
printf(POLYLINE_POINT, x + wc + hs, y + ws - hc); // ( w, -h)
}
}
count++;
}
}
// board outline
if (OUTLINE){
real x = (B.area.x1+B.area.x2)/2 / 10000.0;
real y = (B.area.y1+B.area.y2)/2 / 10000.0;
real w = (B.area.x2-B.area.x1) / 10000.0 / 2;
real h = (B.area.y2-B.area.y1) / 10000.0 / 2;
if (EAGLE6 == 1) {
x = x / E6_SCALE;
y = y / E6_SCALE;
w = w / E6_SCALE;
h = h / E6_SCALE;
}
real wc = w;
real hs = 0;
real ws = 0;
real hc = h;
printf(POLYLINE, 4*CUTTIMES + 1, 1); // 1: closed
printf(POLYLINE_POINT, x + wc, y + ws); // ( w, 0)
for (int i = 0; i < CUTTIMES; i++) {
printf(POLYLINE_POINT, x + wc - hs, y + ws + hc); // ( w, h)
printf(POLYLINE_POINT, x - wc - hs, y - ws + hc); // (-w, h)
printf(POLYLINE_POINT, x - wc + hs, y - ws - hc); // (-w, -h)
printf(POLYLINE_POINT, x + wc + hs, y + ws - hc); // ( w, -h)
}
count++;
}
printf("%s", TRAILER);
return count;
}
board(B) {
int cut_two = 1;
int cut_corner = 0;
int e6_mode = 0;
int ignore_stop = 1;
int outline = 0;
if (EAGLE_VERSION >= 6.0) {
e6_mode = 1;
};
real cut_width = 0.05;
int run = dlgDialog("cream-dxf"){
dlgGroup("Orientation") {
dlgCheckBox("Cut two times for each lines.", cut_two);
dlgCheckBox("Cut off corners of pads. The resulting pads are octagons.", cut_corner);
dlgCheckBox("Ignore pads with no stop flag.", ignore_stop);
dlgCheckBox("Include board outline.", outline);
dlgHBoxLayout {
dlgLabel("Enter the width (float mm) to shrink pads by.");
dlgRealEdit(cut_width, 0.00, 0.10);
};
};
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("-&Cancel") dlgReject();
dlgPushButton("+&Run") dlgAccept();
};
};
CUTTIMES = cut_two ? 2 : 1;
CORNERCUT = cut_corner;
EAGLE6 = e6_mode;
SHRINK_WIDTH = cut_width;
IGNORESTOP = ignore_stop;
OUTLINE = outline;
/*
output("debug.log"){
printf("%d, %d, %d, %f\n", run, CUTTIMES, CORNERCUT, SHRINK_WIDTH);
}
*/
if (run == 1) {
int t, b;
output(filesetext(B.name, "-tcream.dxf")) t = processLayer(B, LAYER_TOP);
output(filesetext(B.name, "-bcream.dxf")) b = processLayer(B, LAYER_BOTTOM);
string message;
sprintf(message, ";DXF files generated with %d+%d objects", t, b); // ';' for information
dlgMessageBox(message);
}
}