diff --git a/cameo/README b/cameo/README index 67407ae..ed4d516 100644 --- a/cameo/README +++ b/cameo/README @@ -45,10 +45,11 @@ translation. File output: write [] + write_gerber [] append [] -Writes all loaded paths in gnuplot format to the specified file. If the -file name is omitted, "write" writes to standard output. +Writes all loaded paths in gnuplot or Gerber format to the specified file. +If the file name is omitted, "write" writes to standard output. "append" is like "write", except that it appends to an existing file. diff --git a/cameo/gerber.c b/cameo/gerber.c index bd7a634..3486e0d 100644 --- a/cameo/gerber.c +++ b/cameo/gerber.c @@ -1,8 +1,8 @@ /* * gerber.c - Gerber file input * - * Written 2010, 2013 by Werner Almesberger - * Copyright 2010, 2013 Werner Almesberger + * Written 2010, 2013, 2015 by Werner Almesberger + * Copyright 2010, 2013, 2015 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -141,3 +141,52 @@ struct path *gerber_read(const char *name, double r_tool_default) fclose(file); return path_connect(paths); } + + +static int gerber_do_write(FILE *file, const struct path *paths) +{ + const struct path *path; + const struct point *p; + + fprintf(file, +"G04 Generated by cameo*\n" +"%%MOMM*%%\n" // dimensions are in mm +"%%FSLAX33Y33*%%\n" // no leading zeroes; absolute; 3 digits int, + // 3 digits fractional +"G01*\n" // linear interpolation +"%%ADD10C,0.01*%%\n" // aperture D10, 10 um circle +"D10*\n"); // select D10 + + for (path = paths; path; path = path->next) + for (p = path->first; p; p = p->next) + fprintf(file, "X%.0fY%.0fD0%u*\n", + p->x * 1000.0, p->y * 1000.0, + p == path->first ? 2 : 1); + + fprintf(file, "M02**\n");// end of file + + if (file == stdout) { + if (fflush(file) == EOF) + return 0; + } else { + if (fclose(file) < 0) + return 0; + } + return 1; +} + + +void gerber_write(const char *name, const struct path *paths) +{ + FILE *file; + + file = name ? fopen(name, "w") : stdout; + if (!file) { + perror(name); + exit(1); + } + if (!gerber_do_write(file, paths)) { + perror(name ? name : "(stdout)"); + exit(1); + } +} diff --git a/cameo/gerber.h b/cameo/gerber.h index 0fb6012..7accfa2 100644 --- a/cameo/gerber.h +++ b/cameo/gerber.h @@ -1,8 +1,8 @@ /* - * gerber.h - Gerber file input + * gerber.h - Gerber file input/output * - * Written 2010 by Werner Almesberger - * Copyright 2010 Werner Almesberger + * Written 2010, 2015 by Werner Almesberger + * Copyright 2010, 2015 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,5 +17,6 @@ struct path *gerber_read(const char *name, double r_tool_default); +void gerber_write(const char *name, const struct path *paths); #endif /* !GERBER_H */ diff --git a/cameo/lang.l b/cameo/lang.l index ac5493b..e1155e9 100644 --- a/cameo/lang.l +++ b/cameo/lang.l @@ -2,8 +2,8 @@ /* * lang.l - Toolpath adaptation language * - * Written 2010-2013 by Werner Almesberger - * Copyright 2010-2013 by Werner Almesberger + * Written 2010-2013, 2015 by Werner Almesberger + * Copyright 2010-2013, 2015 by Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -74,6 +74,8 @@ NUM -?[0-9]+\.?[0-9]* return TOK_STL; } write { BEGIN(FILENAME); return TOK_WRITE; } +write_gerber { BEGIN(FILENAME); + return TOK_WRITE_GERBER; } dog return TOK_DOG; inside return TOK_INSIDE; diff --git a/cameo/lang.y b/cameo/lang.y index 1bd2db2..80834c4 100644 --- a/cameo/lang.y +++ b/cameo/lang.y @@ -2,8 +2,8 @@ /* * lang.y - Toolpath adaptation language * - * Written 2010-2013 by Werner Almesberger - * Copyright 2010-2013 by Werner Almesberger + * Written 2010-2013, 2015 by Werner Almesberger + * Copyright 2010-2013, 2015 by Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -235,6 +235,7 @@ static struct path **classify(struct path **anchor, struct path *path) %token TOK_REVERSE TOK_ROTATE TOK_STATS TOK_STL TOK_TRANSLATE %token TOK_X TOK_Y TOK_Z %token TOK_APPEND TOK_GERBER TOK_GNUPLOT TOK_EXCELLON TOK_WRITE +%token TOK_WRITE_GERBER %token TOK_DOG TOK_INSIDE TOK_ANY %token NUM_EXP_MIL NUM_EXP_MM NUM_IMP_MIL NUM_IMP_MM REF @@ -385,6 +386,10 @@ command: gnuplot_write($2, paths); translate(paths, 0, 0, -zo); } + | TOK_WRITE_GERBER opt_filename + { + gerber_write($2, paths); + } | TOK_APPEND opt_filename { translate(paths, 0, 0, zo); diff --git a/cameo/ops.c b/cameo/ops.c index 9b16ea8..1c24e91 100644 --- a/cameo/ops.c +++ b/cameo/ops.c @@ -41,7 +41,7 @@ struct path *tool_comp_paths(const struct path *paths, int dog_bone, /* * We don't have an algorithm (yet) that can detect which paths are * inside other paths. Therefore, we fake it by looking for the path - * that contains lowest x coordinate. This ought to be the outer + * that contains the lowest x coordinate. This ought to be the outer * boundary of the piece. * * Note that this heuristic falls apart when a job consists of