Index: trunk/scconfig/Rev.h =================================================================== --- trunk/scconfig/Rev.h (revision 24871) +++ trunk/scconfig/Rev.h (revision 24872) @@ -1 +1 @@ -static const int myrev = 24862; +static const int myrev = 24872; Index: trunk/scconfig/Rev.tab =================================================================== --- trunk/scconfig/Rev.tab (revision 24871) +++ trunk/scconfig/Rev.tab (revision 24872) @@ -1,3 +1,4 @@ +24872 configure split excellon exporter from gerber to a separate plugin 24862 configure code simplification: merge hid_flags.[ch] into lib_hid_common 24824 configure move window placement from dialogs to lib_hid_commonfor hidlib cleanup 24816 configure safety wrapper around unlink, opendir, closedir and readdir Index: trunk/scconfig/plugins.h =================================================================== --- trunk/scconfig/plugins.h (revision 24871) +++ trunk/scconfig/plugins.h (revision 24872) @@ -86,6 +86,7 @@ plugin_def("export_bom", "bom pcb_exporter", sbuildin, 1) plugin_def("export_dsn", "specctra .dsn pcb_exporter", sbuildin, 1) plugin_def("export_dxf", "DXF pcb_exporter", sbuildin, 1) +plugin_def("export_excellon", "Excellon drill exporter", sbuildin, 1) plugin_def("export_fidocadj", "FidoCadJ .fcd pcb_exporter", sbuildin, 1) plugin_def("export_gcode", "gcode pcb_exporter", sbuildin, 1) plugin_def("export_gerber", "Gerber pcb_exporter", sbuildin, 1) @@ -133,6 +134,7 @@ plugin_dep("dialogs", "lib_hid_common", 0) plugin_dep("draw_fab", "report", 0) plugin_dep("export_fidocadj", "lib_compat_help", 0) +plugin_dep("export_gerber", "export_excellon", 0) plugin_dep("export_ipcd356", "lib_compat_help", 0) plugin_dep("export_lpr", "export_ps", 0) plugin_dep("export_openems", "lib_polyhelp", 0) Index: trunk/src/Makefile.dep =================================================================== --- trunk/src/Makefile.dep (revision 24871) +++ trunk/src/Makefile.dep (revision 24872) @@ -1149,14 +1149,14 @@ ../src_plugins/export_gcode/auxiliary.h \ ../src_plugins/export_gcode/lists.h ../src_plugins/export_gcode/trace.h \ compat_cc.h -../src_plugins/export_gerber/aperture.o: \ - ../src_plugins/export_gerber/aperture.c ../config.h global_typedefs.h \ - pcb_bool.h unit.h ../src_plugins/export_gerber/aperture.h \ +../src_plugins/export_excellon/aperture.o: \ + ../src_plugins/export_excellon/aperture.c ../config.h global_typedefs.h \ + pcb_bool.h unit.h ../src_plugins/export_excellon/aperture.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h \ ../src_3rd/genvector/genvector_impl.c -../src_plugins/export_gerber/excellon.o: \ - ../src_plugins/export_gerber/excellon.c ../config.h board.h \ +../src_plugins/export_excellon/excellon.o: \ + ../src_plugins/export_excellon/excellon.c ../config.h board.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h global_typedefs.h \ pcb_bool.h unit.h vtroutestyle.h attrib.h \ ../src_3rd/genvector/genvector_impl.h \ @@ -1178,8 +1178,8 @@ hid_draw_helpers.h plugins.h ../src_3rd/puplug/error.h funchash_core.h \ funchash.h funchash_core_list.h conf_core.h \ ../src_plugins/export_gerber/gerber_conf.h conf.h \ - ../src_plugins/export_gerber/excellon.h \ - ../src_plugins/export_gerber/aperture.h + ../src_plugins/export_excellon/excellon.h \ + ../src_plugins/export_excellon/aperture.h ../src_plugins/export_gerber/gerber.o: \ ../src_plugins/export_gerber/gerber.c ../config.h math_helper.h board.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h global_typedefs.h \ @@ -1210,8 +1210,8 @@ funchash.h funchash_core_list.h \ ../src_plugins/export_gerber/gerber_conf.h conf.h hid.h hid_nogui.h \ hid_draw_helpers.h hid_init.h hid_attrib.h hid_inlines.h conf_core.h \ - ../src_plugins/export_gerber/aperture.h \ - ../src_plugins/export_gerber/excellon.h \ + ../src_plugins/export_excellon/aperture.h \ + ../src_plugins/export_excellon/excellon.h \ ../src_plugins/export_gerber/gerber_conf_fields.h ../src_plugins/export_ipcd356/ipcd356.o: \ ../src_plugins/export_ipcd356/ipcd356.c ../config.h board.h \ Index: trunk/src_plugins/export_excellon/Makefile =================================================================== --- trunk/src_plugins/export_excellon/Makefile (nonexistent) +++ trunk/src_plugins/export_excellon/Makefile (revision 24872) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_gerber + +clean: + rm *.o *.so 2>/dev/null ; true Index: trunk/src_plugins/export_excellon/Plug.tmpasm =================================================================== --- trunk/src_plugins/export_excellon/Plug.tmpasm (nonexistent) +++ trunk/src_plugins/export_excellon/Plug.tmpasm (revision 24872) @@ -0,0 +1,13 @@ +put /local/pcb/mod {export_excellon} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/export_excellon/aperture.o + $(PLUGDIR)/export_excellon/excellon.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/export_excellon/excellon_conf.h} + + +switch /local/pcb/export_excellon/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: trunk/src_plugins/export_excellon/aperture.c =================================================================== --- trunk/src_plugins/export_excellon/aperture.c (nonexistent) +++ trunk/src_plugins/export_excellon/aperture.c (revision 24872) @@ -0,0 +1,110 @@ + +#include "config.h" + +#include +#include + +#include "global_typedefs.h" + +#define GVT_DONT_UNDEF +#include "aperture.h" +#include + +void init_aperture_list(aperture_list_t *list) +{ + list->data = NULL; + list->count = 0; +} + +void uninit_aperture_list(aperture_list_t *list) +{ + aperture_t *search = list->data; + aperture_t *next; + while (search) { + next = search->next; + free(search); + search = next; + } + init_aperture_list(list); +} + +aperture_t *add_aperture(aperture_list_t *list, pcb_coord_t width, aperture_shape_t shape) +{ + static int aperture_count; + + aperture_t *app = (aperture_t *) malloc(sizeof *app); + if (app == NULL) + return NULL; + + app->width = width; + app->shape = shape; + app->dCode = DCODE_BASE + aperture_count++; + app->next = list->data; + + list->data = app; + ++list->count; + + return app; +} + +aperture_t *find_aperture(aperture_list_t *list, pcb_coord_t width, aperture_shape_t shape) +{ + aperture_t *search; + + /* we never draw zero-width lines */ + if (width == 0) + return NULL; + + /* Search for an appropriate aperture. */ + for (search = list->data; search; search = search->next) + if (search->width == width && search->shape == shape) + return search; + + /* Failing that, create a new one */ + return add_aperture(list, width, shape); +} + + +/*** drill ***/ + +void pcb_drill_init(pcb_drill_ctx_t *ctx) +{ + vtpdr_init(&ctx->obj); + init_aperture_list(&ctx->apr); +} + +void pcb_drill_uninit(pcb_drill_ctx_t *ctx) +{ + vtpdr_uninit(&ctx->obj); + uninit_aperture_list(&ctx->apr); +} + +pcb_pending_drill_t *pcb_drill_new_pending(pcb_drill_ctx_t *ctx, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2, pcb_coord_t diam) +{ + pcb_pending_drill_t *pd = vtpdr_alloc_append(&ctx->obj, 1); + + pd->x = x1; + pd->y = y1; + pd->x2 = x2; + pd->y2 = y2; + pd->diam = diam; + pd->is_slot = (x1 != x2) || (y1 != y2); + find_aperture(&ctx->apr, diam, ROUND); + return pd; +} + +static int drill_sort_cb(const void *va, const void *vb) +{ + pcb_pending_drill_t *a = (pcb_pending_drill_t *)va; + pcb_pending_drill_t *b = (pcb_pending_drill_t *)vb; + if (a->diam != b->diam) + return a->diam - b->diam; + if (a->x != b->x) + return a->x - a->x; + return b->y - b->y; +} + +void pcb_drill_sort(pcb_drill_ctx_t *ctx) +{ + qsort(ctx->obj.array, ctx->obj.used, sizeof(ctx->obj.array[0]), drill_sort_cb); +} Index: trunk/src_plugins/export_excellon/aperture.h =================================================================== --- trunk/src_plugins/export_excellon/aperture.h (nonexistent) +++ trunk/src_plugins/export_excellon/aperture.h (revision 24872) @@ -0,0 +1,75 @@ +#ifndef PCB_APERTURE_H +#define PCB_APERTURE_H + +/*** generic aperture ***/ + +enum aperture_shape_e { + ROUND, /* Shaped like a circle */ + OCTAGON, /* octagonal shape */ + SQUARE /* Shaped like a square */ +}; +typedef enum aperture_shape_e aperture_shape_t; + +/* This is added to the global aperture array indexes to get gerber + dcode and macro numbers. */ +#define DCODE_BASE 11 + +typedef struct aperture { + int dCode; /* The RS-274X D code */ + pcb_coord_t width; /* Size in pcb units */ + aperture_shape_t shape; /* ROUND/SQUARE etc */ + struct aperture *next; +} aperture_t; + +typedef struct { + aperture_t *data; + int count; +} aperture_list_t; + +void init_aperture_list(aperture_list_t *list); +void uninit_aperture_list(aperture_list_t *list); + +/* Create and add a new aperture to the list */ +aperture_t *add_aperture(aperture_list_t *list, pcb_coord_t width, aperture_shape_t shape); + +/* Fetch an aperture from the list with the specified + * width/shape, creating a new one if none exists */ +aperture_t *find_aperture(aperture_list_t *list, pcb_coord_t width, aperture_shape_t shape); + +/*** drill ***/ + +typedef struct { + pcb_coord_t diam; + pcb_coord_t x; + pcb_coord_t y; + + /* for slots */ + int is_slot; + pcb_coord_t x2; + pcb_coord_t y2; +} pcb_pending_drill_t; + +#define GVT(x) vtpdr_ ## x +#define GVT_ELEM_TYPE pcb_pending_drill_t +#define GVT_SIZE_TYPE size_t +#define GVT_DOUBLING_THRS 2048 +#define GVT_START_SIZE 32 +#define GVT_FUNC +/*#define GVT_SET_NEW_BYTES_TO 0*/ + +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include + +typedef struct pcb_drill_ctx_s { + vtpdr_t obj; + aperture_list_t apr; +} pcb_drill_ctx_t; + +void pcb_drill_init(pcb_drill_ctx_t *ctx); +void pcb_drill_uninit(pcb_drill_ctx_t *ctx); +pcb_pending_drill_t *pcb_drill_new_pending(pcb_drill_ctx_t *ctx, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2, pcb_coord_t diam); +void pcb_drill_sort(pcb_drill_ctx_t *ctx); + +#endif Index: trunk/src_plugins/export_excellon/excellon.c =================================================================== --- trunk/src_plugins/export_excellon/excellon.c (nonexistent) +++ trunk/src_plugins/export_excellon/excellon.c (revision 24872) @@ -0,0 +1,472 @@ +#include "config.h" + +#include "board.h" +#include "global_typedefs.h" +#include "pcb-printf.h" +#include "safe_fs.h" +#include "error.h" +#include "draw.h" +#include "compat_misc.h" +#include "layer.h" +#include "layer_vis.h" +#include "hid.h" +#include "hid_attrib.h" +#include "hid_cam.h" +#include "hid_init.h" +#include "hid_nogui.h" +#include "hid_draw_helpers.h" +#include "plugins.h" +#include "funchash_core.h" +#include "conf_core.h" +#include "excellon_conf.h" + +#include "excellon.h" + +conf_excellon_t conf_excellon; + +#define excellonDrX(pcb, x) ((pcb_coord_t) (x)) +#define excellonDrY(pcb, y) ((pcb_coord_t) ((pcb)->MaxHeight - (y))) + +static pcb_cardinal_t drill_print_objs(pcb_board_t *pcb, FILE *f, pcb_drill_ctx_t *ctx, int force_g85, int slots, pcb_coord_t *excellon_last_tool_dia) +{ + pcb_cardinal_t i, cnt = 0; + int first = 1; + + for (i = 0; i < ctx->obj.used; i++) { + pcb_pending_drill_t *pd = &ctx->obj.array[i]; + if (slots != (!!pd->is_slot)) + continue; + if (i == 0 || pd->diam != *excellon_last_tool_dia) { + aperture_t *ap = find_aperture(&ctx->apr, pd->diam, ROUND); + fprintf(f, "T%02d\r\n", ap->dCode); + *excellon_last_tool_dia = pd->diam; + } + if (pd->is_slot) { + if (first) { + pcb_fprintf(f, "G00"); + first = 0; + } + if (force_g85) + pcb_fprintf(f, "X%06.0mkY%06.0mkG85X%06.0mkY%06.0mk\r\n", excellonDrX(pcb, pd->x), excellonDrY(PCB, pd->y), excellonDrX(pcb, pd->x2), excellonDrY(PCB, pd->y2)); + else + pcb_fprintf(f, "X%06.0mkY%06.0mk\r\nM15\r\nG01X%06.0mkY%06.0mk\r\nM17\r\n", excellonDrX(pcb, pd->x), excellonDrY(PCB, pd->y), excellonDrX(pcb, pd->x2), excellonDrY(PCB, pd->y2)); + first = 1; /* each new slot will need a G00 for some fabs that ignore M17 and M15 */ + } + else { + if (first) { + pcb_fprintf(f, "G05\r\n"); + first = 0; + } + pcb_fprintf(f, "X%06.0mkY%06.0mk\r\n", excellonDrX(pcb, pd->x), excellonDrY(pcb, pd->y)); + } + cnt++; + } + return cnt; +} + +static pcb_cardinal_t drill_print_holes(pcb_board_t *pcb, FILE *f, pcb_drill_ctx_t *ctx, int force_g85) +{ + aperture_t *search; + pcb_cardinal_t cnt = 0; + pcb_coord_t excellon_last_tool_dia = 0; + + /* We omit the ,TZ here because we are not omitting trailing zeros. Our format is + always six-digit 0.1 mil resolution (i.e. 001100 = 0.11") */ + fprintf(f, "M48\r\n" "INCH\r\n"); + for (search = ctx->apr.data; search; search = search->next) + pcb_fprintf(f, "T%02dC%.3mi\r\n", search->dCode, search->width); + fprintf(f, "%%\r\n"); + + /* dump pending drills in sequence */ + pcb_drill_sort(ctx); + cnt += drill_print_objs(pcb, f, ctx, force_g85, 0, &excellon_last_tool_dia); + cnt += drill_print_objs(pcb, f, ctx, force_g85, 1, &excellon_last_tool_dia); + return cnt; +} + +void pcb_drill_export_excellon(pcb_board_t *pcb, pcb_drill_ctx_t *ctx, int force_g85, const char *fn) +{ + FILE *f = pcb_fopen(fn, "wb"); /* Binary needed to force CR-LF */ + if (f == NULL) { + pcb_message(PCB_MSG_ERROR, "Error: Could not open %s for writing the excellon file.\n", fn); + return; + } + + if (ctx->obj.used > 0) + drill_print_holes(pcb, f, ctx, force_g85); + + fprintf(f, "M30\r\n"); + fclose(f); +} + +/*** HID ***/ +static pcb_hid_t excellon_hid; +static const char *excellon_cookie = "excellon drill/cnc exporter"; + +#define SUFF_LEN 32 + +/* global exporter states */ +static int is_plated, finding_apertures; +static pcb_drill_ctx_t pdrills, udrills; +static pcb_cam_t excellon_cam; +static pcb_coord_t lastwidth; +static char *filename = NULL; +static struct { + unsigned nonround:1; + unsigned arc:1; + unsigned poly:1; + unsigned comp:1; +} warn; + +typedef struct hid_gc_s { + pcb_core_gc_t core_gc; + pcb_cap_style_t style; + pcb_coord_t width; +} hid_gc_s; + +static pcb_hid_attribute_t excellon_options[] = { + +/* %start-doc options "90 excellon Export" +@ftable @code +@item --excellonfile +excellon output file prefix. Can include a path. +@end ftable +%end-doc +*/ + {"filename", "excellon output file base - used to generate default plated and/or unplated file name in case they are not specified", + PCB_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_excellonfile 0 + + {"filename-plated", "excellon output file name for plated features", + PCB_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_excellonfile_plated 1 + + {"filename-unplated", "excellon output file name for unplated features", + PCB_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_excellonfile_unplated 2 + + {"cam", "CAM instruction", + PCB_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 3 +}; + +#define NUM_OPTIONS (sizeof(excellon_options)/sizeof(excellon_options[0])) + +static pcb_hid_attr_val_t excellon_values[NUM_OPTIONS]; + +static pcb_hid_attribute_t *excellon_get_export_options(int *n) +{ + if ((PCB != NULL) && (excellon_options[HA_excellonfile].default_val.str_value == NULL)) + pcb_derive_default_filename(PCB->Filename, &excellon_options[HA_excellonfile], ""); + + if (n) + *n = NUM_OPTIONS; + return excellon_options; +} + +static void excellon_do_export(pcb_hid_attr_val_t * options) +{ + const char *fnbase, *fn; + char *filesuff; + int i; + int save_ons[PCB_MAX_LAYER + 2]; + pcb_hid_expose_ctx_t ctx; + + conf_force_set_bool(conf_core.editor.thin_draw, 0); + conf_force_set_bool(conf_core.editor.thin_draw_poly, 0); + conf_force_set_bool(conf_core.editor.check_planes, 0); + + pcb_drill_init(&pdrills); + pcb_drill_init(&udrills); + memset(&warn, 0, sizeof(warn)); + + if (!options) { + excellon_get_export_options(NULL); + for (i = 0; i < NUM_OPTIONS; i++) + excellon_values[i] = excellon_options[i].default_val; + options = excellon_values; + } + + pcb_cam_begin(PCB, &excellon_cam, options[HA_cam].str_value, excellon_options, NUM_OPTIONS, options); + + fnbase = options[HA_excellonfile].str_value; + if (!fnbase) + fnbase = "pcb-out"; + + i = strlen(fnbase); + filename = (char *) realloc(filename, i + SUFF_LEN); + strcpy(filename, fnbase); + filesuff = filename + strlen(filename); + + if (!excellon_cam.active) + pcb_hid_save_and_show_layer_ons(save_ons); + + ctx.view.X1 = 0; + ctx.view.Y1 = 0; + ctx.view.X2 = PCB->MaxWidth; + ctx.view.Y2 = PCB->MaxHeight; + + lastwidth = -1; + finding_apertures = 1; + pcb_hid_expose_all(&excellon_hid, &ctx, NULL); + + lastwidth = -1; + finding_apertures = 0; + pcb_hid_expose_all(&excellon_hid, &ctx, NULL); + conf_update(NULL, -1); /* resotre forced sets */ + + + if (excellon_cam.active) { + fn = excellon_cam.fn; + pcb_drill_export_excellon(PCB, &pdrills, conf_excellon.plugins.export_excellon.plated_g85_slot, fn); + } + else { + if (options[HA_excellonfile_plated].str_value == NULL) { + strcpy(filesuff, ".plated.cnc"); + fn = filename; + } + else + fn = options[HA_excellonfile_plated].str_value; + pcb_drill_export_excellon(PCB, &pdrills, conf_excellon.plugins.export_excellon.plated_g85_slot, fn); + + if (options[HA_excellonfile_unplated].str_value == NULL) { + strcpy(filesuff, ".unplated.cnc"); + fn = filename; + } + else + fn = options[HA_excellonfile_unplated].str_value; + pcb_drill_export_excellon(PCB, &udrills, conf_excellon.plugins.export_excellon.unplated_g85_slot, fn); + } + + if (pcb_cam_end(&excellon_cam) == 0) + pcb_message(PCB_MSG_ERROR, "excellon cam export for '%s' failed to produce any content\n", options[HA_cam].str_value); + + pcb_drill_uninit(&pdrills); + pcb_drill_uninit(&udrills); +} + + +static int excellon_parse_arguments(int *argc, char ***argv) +{ + pcb_hid_register_attributes(excellon_options, NUM_OPTIONS, excellon_cookie, 0); + return pcb_hid_parse_command_line(argc, argv); +} + +static int excellon_set_layer_group(pcb_layergrp_id_t group, const char *purpose, int purpi, pcb_layer_id_t layer, unsigned int flags, int is_empty, pcb_xform_t **xform) +{ + int is_drill; + + /* before cam lets this happen... */ + if (PCB_LAYER_IS_ASSY(flags, purpi)) + return 0; + + pcb_cam_set_layer_group(&excellon_cam, group, purpose, purpi, flags, xform); + + if (flags & PCB_LYT_UI) + return 0; + + is_drill = PCB_LAYER_IS_DRILL(flags, purpi) || ((flags & PCB_LYT_MECH) && PCB_LAYER_IS_ROUTE(flags, purpi)); + if (!is_drill) + return 0; + + is_plated = PCB_LAYER_IS_PROUTE(flags, purpi) || PCB_LAYER_IS_PDRILL(flags, purpi); + return 1; +} + +static pcb_hid_gc_t excellon_make_gc(void) +{ + pcb_hid_gc_t rv = calloc(1, sizeof(*rv)); + return rv; +} + +static void excellon_destroy_gc(pcb_hid_gc_t gc) +{ + free(gc); +} + +static void excellon_set_drawing_mode(pcb_composite_op_t op, pcb_bool direct, const pcb_box_t *drw_screen) +{ + switch(op) { + case PCB_HID_COMP_RESET: + case PCB_HID_COMP_POSITIVE: + case PCB_HID_COMP_FLUSH: + break; + + case PCB_HID_COMP_POSITIVE_XOR: + case PCB_HID_COMP_NEGATIVE: + if (!warn.comp) { + warn.comp = 1; + pcb_message(PCB_MSG_ERROR, "Excellon: can not draw composite layers (some features may be missing from the export)\n"); + } + } +} + +static void excellon_set_color(pcb_hid_gc_t gc, const pcb_color_t *color) +{ +} + +static void excellon_set_line_cap(pcb_hid_gc_t gc, pcb_cap_style_t style) +{ + gc->style = style; +} + +static void excellon_set_line_width(pcb_hid_gc_t gc, pcb_coord_t width) +{ + gc->width = width; +} + +static void excellon_set_draw_xor(pcb_hid_gc_t gc, int xor_) +{ +} + +pcb_drill_ctx_t *get_drill_ctx(void) +{ + if (excellon_cam.active) + return &pdrills; + + return (is_plated ? &pdrills : &udrills); +} + +static void use_gc(pcb_hid_gc_t gc, pcb_coord_t radius) +{ + if ((gc->style != pcb_cap_round) && (!warn.nonround)) { + warn.nonround = 1; + pcb_message(PCB_MSG_ERROR, "Excellon: can not set non-round aperture (some features may be missing from the export)\n"); + } + + if (radius == 0) + radius = gc->width; + else + radius *= 2; + + if (radius != lastwidth) { + aperture_t *aptr = find_aperture(&(get_drill_ctx()->apr), radius, ROUND); + if (aptr == NULL) + pcb_fprintf(stderr, "error: aperture for radius %$mS type ROUND is null\n", radius); + lastwidth = radius; + } +} + + +static void excellon_draw_line(pcb_hid_gc_t gc, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2) +{ + pcb_coord_t dia = gc->width/2; + + find_aperture(&(get_drill_ctx()->apr), dia*2, ROUND); + + if (!finding_apertures) + pcb_drill_new_pending(get_drill_ctx(), x1, y1, x2, y2, dia*2); +} + +static void excellon_draw_rect(pcb_hid_gc_t gc, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2) +{ + excellon_draw_line(gc, x1, y1, x1, y2); + excellon_draw_line(gc, x1, y1, x2, y1); + excellon_draw_line(gc, x1, y2, x2, y2); + excellon_draw_line(gc, x2, y1, x2, y2); +} + +static void excellon_draw_arc(pcb_hid_gc_t gc, pcb_coord_t cx, pcb_coord_t cy, pcb_coord_t width, pcb_coord_t height, pcb_angle_t start_angle, pcb_angle_t delta_angle) +{ + if (!warn.arc) { + warn.arc = 1; + pcb_message(PCB_MSG_ERROR, "Excellon: can not export arcs (some features may be missing from the export)\n"); + } +} + +static void excellon_fill_circle(pcb_hid_gc_t gc, pcb_coord_t cx, pcb_coord_t cy, pcb_coord_t radius) +{ + if (radius <= 0) + return; + + radius = 50 * pcb_round(radius / 50.0); + use_gc(gc, radius); + if (!finding_apertures) + pcb_drill_new_pending(get_drill_ctx(), cx, cy, cx, cy, radius * 2); +} + +static void excellon_fill_polygon_offs(pcb_hid_gc_t gc, int n_coords, pcb_coord_t *x, pcb_coord_t *y, pcb_coord_t dx, pcb_coord_t dy) +{ + if (!warn.poly) { + warn.poly = 1; + pcb_message(PCB_MSG_ERROR, "Excellon: can not export polygons (some features may be missing from the export)\n"); + } +} + +static void excellon_fill_polygon(pcb_hid_gc_t gc, int n_coords, pcb_coord_t *x, pcb_coord_t *y) +{ + excellon_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + + +static void excellon_fill_rect(pcb_hid_gc_t gc, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2) +{ + excellon_fill_polygon(gc, 0, NULL, NULL); +} + +static void excellon_calibrate(double xval, double yval) +{ + pcb_message(PCB_MSG_ERROR, "Excellon internal error: can not calibrate()\n"); +} + +static int excellon_usage(const char *topic) +{ + fprintf(stderr, "\nexcellon exporter command line arguments:\n\n"); + pcb_hid_usage(excellon_options, sizeof(excellon_options) / sizeof(excellon_options[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x excellon [excellon options] foo.pcb\n\n"); + return 0; +} + +static void excellon_set_crosshair(pcb_coord_t x, pcb_coord_t y, int action) +{ +} + + + +int pplg_check_ver_export_excellon(int ver_needed) { return 0; } + +void pplg_uninit_export_excellon(void) +{ + pcb_hid_remove_attributes_by_cookie(excellon_cookie); + free(filename); +} + +int pplg_init_export_excellon(void) +{ + PCB_API_CHK_VER; + + memset(&excellon_hid, 0, sizeof(excellon_hid)); + + pcb_hid_nogui_init(&excellon_hid); + pcb_dhlp_draw_helpers_init(&excellon_hid); + + excellon_hid.struct_size = sizeof(excellon_hid); + excellon_hid.name = "excellon"; + excellon_hid.description = "excellon drill/boundary export"; + excellon_hid.exporter = 1; + + excellon_hid.get_export_options = excellon_get_export_options; + excellon_hid.do_export = excellon_do_export; + excellon_hid.parse_arguments = excellon_parse_arguments; + excellon_hid.set_layer_group = excellon_set_layer_group; + excellon_hid.make_gc = excellon_make_gc; + excellon_hid.destroy_gc = excellon_destroy_gc; + excellon_hid.set_drawing_mode = excellon_set_drawing_mode; + excellon_hid.set_color = excellon_set_color; + excellon_hid.set_line_cap = excellon_set_line_cap; + excellon_hid.set_line_width = excellon_set_line_width; + excellon_hid.set_draw_xor = excellon_set_draw_xor; + excellon_hid.draw_line = excellon_draw_line; + excellon_hid.draw_arc = excellon_draw_arc; + excellon_hid.draw_rect = excellon_draw_rect; + excellon_hid.fill_circle = excellon_fill_circle; + excellon_hid.fill_polygon = excellon_fill_polygon; + excellon_hid.fill_polygon_offs = excellon_fill_polygon_offs; + excellon_hid.fill_rect = excellon_fill_rect; + excellon_hid.calibrate = excellon_calibrate; + excellon_hid.set_crosshair = excellon_set_crosshair; + excellon_hid.usage = excellon_usage; + + pcb_hid_register_hid(&excellon_hid); + return 0; +} Index: trunk/src_plugins/export_excellon/excellon.h =================================================================== --- trunk/src_plugins/export_excellon/excellon.h (nonexistent) +++ trunk/src_plugins/export_excellon/excellon.h (revision 24872) @@ -0,0 +1,12 @@ +#ifndef PCB_DRILL_H +#define PCB_DRILL_H + +#include "aperture.h" + +void pcb_drill_export_excellon(pcb_board_t *pcb, pcb_drill_ctx_t *ctx, int force_g85, const char *fn); + +int pplg_check_ver_export_excellon(int ver_needed); +void pplg_uninit_export_excellon(void); +int pplg_init_export_excellon(void); + +#endif Index: trunk/src_plugins/export_excellon/excellon_conf.h =================================================================== --- trunk/src_plugins/export_excellon/excellon_conf.h (nonexistent) +++ trunk/src_plugins/export_excellon/excellon_conf.h (revision 24872) @@ -0,0 +1,15 @@ +#ifndef PCB_EXCELLON_CONF_H +#define PCB_EXCELLON_CONF_H + +#include "conf.h" + +typedef struct { + const struct plugins { + const struct export_excellon { + CFT_BOOLEAN plated_g85_slot; /* use G85 (drill cycle instead of route) for plated slots */ + CFT_BOOLEAN unplated_g85_slot; /* use G85 (drill cycle instead of route) for unplated slots */ + } export_excellon; + } plugins; +} conf_excellon_t; + +#endif Index: trunk/src_plugins/export_excellon/export_excellon.pup =================================================================== --- trunk/src_plugins/export_excellon/export_excellon.pup (nonexistent) +++ trunk/src_plugins/export_excellon/export_excellon.pup (revision 24872) @@ -0,0 +1,9 @@ +$class export +$short Excellon drill exporter +$long Export to excellon drill/cnc files +$state works +$fmt-native no +$fmt-feature-w export excellon drill/cnc for PCB fabbing, multiple files (configurable) +$package export +default buildin +autoload 1 Index: trunk/src_plugins/export_gerber/aperture.c =================================================================== --- trunk/src_plugins/export_gerber/aperture.c (revision 24871) +++ trunk/src_plugins/export_gerber/aperture.c (nonexistent) @@ -1,110 +0,0 @@ - -#include "config.h" - -#include -#include - -#include "global_typedefs.h" - -#define GVT_DONT_UNDEF -#include "aperture.h" -#include - -void init_aperture_list(aperture_list_t *list) -{ - list->data = NULL; - list->count = 0; -} - -void uninit_aperture_list(aperture_list_t *list) -{ - aperture_t *search = list->data; - aperture_t *next; - while (search) { - next = search->next; - free(search); - search = next; - } - init_aperture_list(list); -} - -aperture_t *add_aperture(aperture_list_t *list, pcb_coord_t width, aperture_shape_t shape) -{ - static int aperture_count; - - aperture_t *app = (aperture_t *) malloc(sizeof *app); - if (app == NULL) - return NULL; - - app->width = width; - app->shape = shape; - app->dCode = DCODE_BASE + aperture_count++; - app->next = list->data; - - list->data = app; - ++list->count; - - return app; -} - -aperture_t *find_aperture(aperture_list_t *list, pcb_coord_t width, aperture_shape_t shape) -{ - aperture_t *search; - - /* we never draw zero-width lines */ - if (width == 0) - return NULL; - - /* Search for an appropriate aperture. */ - for (search = list->data; search; search = search->next) - if (search->width == width && search->shape == shape) - return search; - - /* Failing that, create a new one */ - return add_aperture(list, width, shape); -} - - -/*** drill ***/ - -void pcb_drill_init(pcb_drill_ctx_t *ctx) -{ - vtpdr_init(&ctx->obj); - init_aperture_list(&ctx->apr); -} - -void pcb_drill_uninit(pcb_drill_ctx_t *ctx) -{ - vtpdr_uninit(&ctx->obj); - uninit_aperture_list(&ctx->apr); -} - -pcb_pending_drill_t *pcb_drill_new_pending(pcb_drill_ctx_t *ctx, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2, pcb_coord_t diam) -{ - pcb_pending_drill_t *pd = vtpdr_alloc_append(&ctx->obj, 1); - - pd->x = x1; - pd->y = y1; - pd->x2 = x2; - pd->y2 = y2; - pd->diam = diam; - pd->is_slot = (x1 != x2) || (y1 != y2); - find_aperture(&ctx->apr, diam, ROUND); - return pd; -} - -static int drill_sort_cb(const void *va, const void *vb) -{ - pcb_pending_drill_t *a = (pcb_pending_drill_t *)va; - pcb_pending_drill_t *b = (pcb_pending_drill_t *)vb; - if (a->diam != b->diam) - return a->diam - b->diam; - if (a->x != b->x) - return a->x - a->x; - return b->y - b->y; -} - -void pcb_drill_sort(pcb_drill_ctx_t *ctx) -{ - qsort(ctx->obj.array, ctx->obj.used, sizeof(ctx->obj.array[0]), drill_sort_cb); -} Index: trunk/src_plugins/export_gerber/aperture.h =================================================================== --- trunk/src_plugins/export_gerber/aperture.h (revision 24871) +++ trunk/src_plugins/export_gerber/aperture.h (nonexistent) @@ -1,75 +0,0 @@ -#ifndef PCB_APERTURE_H -#define PCB_APERTURE_H - -/*** generic aperture ***/ - -enum aperture_shape_e { - ROUND, /* Shaped like a circle */ - OCTAGON, /* octagonal shape */ - SQUARE /* Shaped like a square */ -}; -typedef enum aperture_shape_e aperture_shape_t; - -/* This is added to the global aperture array indexes to get gerber - dcode and macro numbers. */ -#define DCODE_BASE 11 - -typedef struct aperture { - int dCode; /* The RS-274X D code */ - pcb_coord_t width; /* Size in pcb units */ - aperture_shape_t shape; /* ROUND/SQUARE etc */ - struct aperture *next; -} aperture_t; - -typedef struct { - aperture_t *data; - int count; -} aperture_list_t; - -void init_aperture_list(aperture_list_t *list); -void uninit_aperture_list(aperture_list_t *list); - -/* Create and add a new aperture to the list */ -aperture_t *add_aperture(aperture_list_t *list, pcb_coord_t width, aperture_shape_t shape); - -/* Fetch an aperture from the list with the specified - * width/shape, creating a new one if none exists */ -aperture_t *find_aperture(aperture_list_t *list, pcb_coord_t width, aperture_shape_t shape); - -/*** drill ***/ - -typedef struct { - pcb_coord_t diam; - pcb_coord_t x; - pcb_coord_t y; - - /* for slots */ - int is_slot; - pcb_coord_t x2; - pcb_coord_t y2; -} pcb_pending_drill_t; - -#define GVT(x) vtpdr_ ## x -#define GVT_ELEM_TYPE pcb_pending_drill_t -#define GVT_SIZE_TYPE size_t -#define GVT_DOUBLING_THRS 2048 -#define GVT_START_SIZE 32 -#define GVT_FUNC -/*#define GVT_SET_NEW_BYTES_TO 0*/ - -#include -#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) -#define GVT_FREE(vect, ptr) free(ptr) -#include - -typedef struct pcb_drill_ctx_s { - vtpdr_t obj; - aperture_list_t apr; -} pcb_drill_ctx_t; - -void pcb_drill_init(pcb_drill_ctx_t *ctx); -void pcb_drill_uninit(pcb_drill_ctx_t *ctx); -pcb_pending_drill_t *pcb_drill_new_pending(pcb_drill_ctx_t *ctx, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2, pcb_coord_t diam); -void pcb_drill_sort(pcb_drill_ctx_t *ctx); - -#endif Index: trunk/src_plugins/export_gerber/excellon.c =================================================================== --- trunk/src_plugins/export_gerber/excellon.c (revision 24871) +++ trunk/src_plugins/export_gerber/excellon.c (nonexistent) @@ -1,472 +0,0 @@ -#include "config.h" - -#include "board.h" -#include "global_typedefs.h" -#include "pcb-printf.h" -#include "safe_fs.h" -#include "error.h" -#include "draw.h" -#include "compat_misc.h" -#include "layer.h" -#include "layer_vis.h" -#include "hid.h" -#include "hid_attrib.h" -#include "hid_cam.h" -#include "hid_init.h" -#include "hid_nogui.h" -#include "hid_draw_helpers.h" -#include "plugins.h" -#include "funchash_core.h" -#include "conf_core.h" -#include "gerber_conf.h" - -#include "excellon.h" - -extern conf_gerber_t conf_gerber; - -#define gerberDrX(pcb, x) ((pcb_coord_t) (x)) -#define gerberDrY(pcb, y) ((pcb_coord_t) ((pcb)->MaxHeight - (y))) - -static pcb_cardinal_t drill_print_objs(pcb_board_t *pcb, FILE *f, pcb_drill_ctx_t *ctx, int force_g85, int slots, pcb_coord_t *excellon_last_tool_dia) -{ - pcb_cardinal_t i, cnt = 0; - int first = 1; - - for (i = 0; i < ctx->obj.used; i++) { - pcb_pending_drill_t *pd = &ctx->obj.array[i]; - if (slots != (!!pd->is_slot)) - continue; - if (i == 0 || pd->diam != *excellon_last_tool_dia) { - aperture_t *ap = find_aperture(&ctx->apr, pd->diam, ROUND); - fprintf(f, "T%02d\r\n", ap->dCode); - *excellon_last_tool_dia = pd->diam; - } - if (pd->is_slot) { - if (first) { - pcb_fprintf(f, "G00"); - first = 0; - } - if (force_g85) - pcb_fprintf(f, "X%06.0mkY%06.0mkG85X%06.0mkY%06.0mk\r\n", gerberDrX(pcb, pd->x), gerberDrY(PCB, pd->y), gerberDrX(pcb, pd->x2), gerberDrY(PCB, pd->y2)); - else - pcb_fprintf(f, "X%06.0mkY%06.0mk\r\nM15\r\nG01X%06.0mkY%06.0mk\r\nM17\r\n", gerberDrX(pcb, pd->x), gerberDrY(PCB, pd->y), gerberDrX(pcb, pd->x2), gerberDrY(PCB, pd->y2)); - first = 1; /* each new slot will need a G00 for some fabs that ignore M17 and M15 */ - } - else { - if (first) { - pcb_fprintf(f, "G05\r\n"); - first = 0; - } - pcb_fprintf(f, "X%06.0mkY%06.0mk\r\n", gerberDrX(pcb, pd->x), gerberDrY(pcb, pd->y)); - } - cnt++; - } - return cnt; -} - -static pcb_cardinal_t drill_print_holes(pcb_board_t *pcb, FILE *f, pcb_drill_ctx_t *ctx, int force_g85) -{ - aperture_t *search; - pcb_cardinal_t cnt = 0; - pcb_coord_t excellon_last_tool_dia = 0; - - /* We omit the ,TZ here because we are not omitting trailing zeros. Our format is - always six-digit 0.1 mil resolution (i.e. 001100 = 0.11") */ - fprintf(f, "M48\r\n" "INCH\r\n"); - for (search = ctx->apr.data; search; search = search->next) - pcb_fprintf(f, "T%02dC%.3mi\r\n", search->dCode, search->width); - fprintf(f, "%%\r\n"); - - /* dump pending drills in sequence */ - pcb_drill_sort(ctx); - cnt += drill_print_objs(pcb, f, ctx, force_g85, 0, &excellon_last_tool_dia); - cnt += drill_print_objs(pcb, f, ctx, force_g85, 1, &excellon_last_tool_dia); - return cnt; -} - -void pcb_drill_export_excellon(pcb_board_t *pcb, pcb_drill_ctx_t *ctx, int force_g85, const char *fn) -{ - FILE *f = pcb_fopen(fn, "wb"); /* Binary needed to force CR-LF */ - if (f == NULL) { - pcb_message(PCB_MSG_ERROR, "Error: Could not open %s for writing the excellon file.\n", fn); - return; - } - - if (ctx->obj.used > 0) - drill_print_holes(pcb, f, ctx, force_g85); - - fprintf(f, "M30\r\n"); - fclose(f); -} - -/*** HID ***/ -static pcb_hid_t excellon_hid; -static const char *excellon_cookie = "gerber exporter: excellon"; - -#define SUFF_LEN 32 - -/* global exporter states */ -static int is_plated, finding_apertures; -static pcb_drill_ctx_t pdrills, udrills; -static pcb_cam_t excellon_cam; -static pcb_coord_t lastwidth; -static char *filename = NULL; -static struct { - unsigned nonround:1; - unsigned arc:1; - unsigned poly:1; - unsigned comp:1; -} warn; - -typedef struct hid_gc_s { - pcb_core_gc_t core_gc; - pcb_cap_style_t style; - pcb_coord_t width; -} hid_gc_s; - -static pcb_hid_attribute_t excellon_options[] = { - -/* %start-doc options "90 excellon Export" -@ftable @code -@item --excellonfile -excellon output file prefix. Can include a path. -@end ftable -%end-doc -*/ - {"filename", "excellon output file base - used to generate default plated and/or unplated file name in case they are not specified", - PCB_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, -#define HA_excellonfile 0 - - {"filename-plated", "excellon output file name for plated features", - PCB_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, -#define HA_excellonfile_plated 1 - - {"filename-unplated", "excellon output file name for unplated features", - PCB_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, -#define HA_excellonfile_unplated 2 - - {"cam", "CAM instruction", - PCB_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, -#define HA_cam 3 -}; - -#define NUM_OPTIONS (sizeof(excellon_options)/sizeof(excellon_options[0])) - -static pcb_hid_attr_val_t excellon_values[NUM_OPTIONS]; - -static pcb_hid_attribute_t *excellon_get_export_options(int *n) -{ - if ((PCB != NULL) && (excellon_options[HA_excellonfile].default_val.str_value == NULL)) - pcb_derive_default_filename(PCB->Filename, &excellon_options[HA_excellonfile], ""); - - if (n) - *n = NUM_OPTIONS; - return excellon_options; -} - -static void excellon_do_export(pcb_hid_attr_val_t * options) -{ - const char *fnbase, *fn; - char *filesuff; - int i; - int save_ons[PCB_MAX_LAYER + 2]; - pcb_hid_expose_ctx_t ctx; - - conf_force_set_bool(conf_core.editor.thin_draw, 0); - conf_force_set_bool(conf_core.editor.thin_draw_poly, 0); - conf_force_set_bool(conf_core.editor.check_planes, 0); - - pcb_drill_init(&pdrills); - pcb_drill_init(&udrills); - memset(&warn, 0, sizeof(warn)); - - if (!options) { - excellon_get_export_options(NULL); - for (i = 0; i < NUM_OPTIONS; i++) - excellon_values[i] = excellon_options[i].default_val; - options = excellon_values; - } - - pcb_cam_begin(PCB, &excellon_cam, options[HA_cam].str_value, excellon_options, NUM_OPTIONS, options); - - fnbase = options[HA_excellonfile].str_value; - if (!fnbase) - fnbase = "pcb-out"; - - i = strlen(fnbase); - filename = (char *) realloc(filename, i + SUFF_LEN); - strcpy(filename, fnbase); - filesuff = filename + strlen(filename); - - if (!excellon_cam.active) - pcb_hid_save_and_show_layer_ons(save_ons); - - ctx.view.X1 = 0; - ctx.view.Y1 = 0; - ctx.view.X2 = PCB->MaxWidth; - ctx.view.Y2 = PCB->MaxHeight; - - lastwidth = -1; - finding_apertures = 1; - pcb_hid_expose_all(&excellon_hid, &ctx, NULL); - - lastwidth = -1; - finding_apertures = 0; - pcb_hid_expose_all(&excellon_hid, &ctx, NULL); - conf_update(NULL, -1); /* resotre forced sets */ - - - if (excellon_cam.active) { - fn = excellon_cam.fn; - pcb_drill_export_excellon(PCB, &pdrills, conf_gerber.plugins.export_gerber.plated_g85_slot, fn); - } - else { - if (options[HA_excellonfile_plated].str_value == NULL) { - strcpy(filesuff, ".plated.cnc"); - fn = filename; - } - else - fn = options[HA_excellonfile_plated].str_value; - pcb_drill_export_excellon(PCB, &pdrills, conf_gerber.plugins.export_gerber.plated_g85_slot, fn); - - if (options[HA_excellonfile_unplated].str_value == NULL) { - strcpy(filesuff, ".unplated.cnc"); - fn = filename; - } - else - fn = options[HA_excellonfile_unplated].str_value; - pcb_drill_export_excellon(PCB, &udrills, conf_gerber.plugins.export_gerber.unplated_g85_slot, fn); - } - - if (pcb_cam_end(&excellon_cam) == 0) - pcb_message(PCB_MSG_ERROR, "excellon cam export for '%s' failed to produce any content\n", options[HA_cam].str_value); - - pcb_drill_uninit(&pdrills); - pcb_drill_uninit(&udrills); -} - - -static int excellon_parse_arguments(int *argc, char ***argv) -{ - pcb_hid_register_attributes(excellon_options, NUM_OPTIONS, excellon_cookie, 0); - return pcb_hid_parse_command_line(argc, argv); -} - -static int excellon_set_layer_group(pcb_layergrp_id_t group, const char *purpose, int purpi, pcb_layer_id_t layer, unsigned int flags, int is_empty, pcb_xform_t **xform) -{ - int is_drill; - - /* before cam lets this happen... */ - if (PCB_LAYER_IS_ASSY(flags, purpi)) - return 0; - - pcb_cam_set_layer_group(&excellon_cam, group, purpose, purpi, flags, xform); - - if (flags & PCB_LYT_UI) - return 0; - - is_drill = PCB_LAYER_IS_DRILL(flags, purpi) || ((flags & PCB_LYT_MECH) && PCB_LAYER_IS_ROUTE(flags, purpi)); - if (!is_drill) - return 0; - - is_plated = PCB_LAYER_IS_PROUTE(flags, purpi) || PCB_LAYER_IS_PDRILL(flags, purpi); - return 1; -} - -static pcb_hid_gc_t excellon_make_gc(void) -{ - pcb_hid_gc_t rv = calloc(1, sizeof(*rv)); - return rv; -} - -static void excellon_destroy_gc(pcb_hid_gc_t gc) -{ - free(gc); -} - -static void excellon_set_drawing_mode(pcb_composite_op_t op, pcb_bool direct, const pcb_box_t *drw_screen) -{ - switch(op) { - case PCB_HID_COMP_RESET: - case PCB_HID_COMP_POSITIVE: - case PCB_HID_COMP_FLUSH: - break; - - case PCB_HID_COMP_POSITIVE_XOR: - case PCB_HID_COMP_NEGATIVE: - if (!warn.comp) { - warn.comp = 1; - pcb_message(PCB_MSG_ERROR, "Excellon: can not draw composite layers (some features may be missing from the export)\n"); - } - } -} - -static void excellon_set_color(pcb_hid_gc_t gc, const pcb_color_t *color) -{ -} - -static void excellon_set_line_cap(pcb_hid_gc_t gc, pcb_cap_style_t style) -{ - gc->style = style; -} - -static void excellon_set_line_width(pcb_hid_gc_t gc, pcb_coord_t width) -{ - gc->width = width; -} - -static void excellon_set_draw_xor(pcb_hid_gc_t gc, int xor_) -{ -} - -pcb_drill_ctx_t *get_drill_ctx(void) -{ - if (excellon_cam.active) - return &pdrills; - - return (is_plated ? &pdrills : &udrills); -} - -static void use_gc(pcb_hid_gc_t gc, pcb_coord_t radius) -{ - if ((gc->style != pcb_cap_round) && (!warn.nonround)) { - warn.nonround = 1; - pcb_message(PCB_MSG_ERROR, "Excellon: can not set non-round aperture (some features may be missing from the export)\n"); - } - - if (radius == 0) - radius = gc->width; - else - radius *= 2; - - if (radius != lastwidth) { - aperture_t *aptr = find_aperture(&(get_drill_ctx()->apr), radius, ROUND); - if (aptr == NULL) - pcb_fprintf(stderr, "error: aperture for radius %$mS type ROUND is null\n", radius); - lastwidth = radius; - } -} - - -static void excellon_draw_line(pcb_hid_gc_t gc, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2) -{ - pcb_coord_t dia = gc->width/2; - - find_aperture(&(get_drill_ctx()->apr), dia*2, ROUND); - - if (!finding_apertures) - pcb_drill_new_pending(get_drill_ctx(), x1, y1, x2, y2, dia*2); -} - -static void excellon_draw_rect(pcb_hid_gc_t gc, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2) -{ - excellon_draw_line(gc, x1, y1, x1, y2); - excellon_draw_line(gc, x1, y1, x2, y1); - excellon_draw_line(gc, x1, y2, x2, y2); - excellon_draw_line(gc, x2, y1, x2, y2); -} - -static void excellon_draw_arc(pcb_hid_gc_t gc, pcb_coord_t cx, pcb_coord_t cy, pcb_coord_t width, pcb_coord_t height, pcb_angle_t start_angle, pcb_angle_t delta_angle) -{ - if (!warn.arc) { - warn.arc = 1; - pcb_message(PCB_MSG_ERROR, "Excellon: can not export arcs (some features may be missing from the export)\n"); - } -} - -static void excellon_fill_circle(pcb_hid_gc_t gc, pcb_coord_t cx, pcb_coord_t cy, pcb_coord_t radius) -{ - if (radius <= 0) - return; - - radius = 50 * pcb_round(radius / 50.0); - use_gc(gc, radius); - if (!finding_apertures) - pcb_drill_new_pending(get_drill_ctx(), cx, cy, cx, cy, radius * 2); -} - -static void excellon_fill_polygon_offs(pcb_hid_gc_t gc, int n_coords, pcb_coord_t *x, pcb_coord_t *y, pcb_coord_t dx, pcb_coord_t dy) -{ - if (!warn.poly) { - warn.poly = 1; - pcb_message(PCB_MSG_ERROR, "Excellon: can not export polygons (some features may be missing from the export)\n"); - } -} - -static void excellon_fill_polygon(pcb_hid_gc_t gc, int n_coords, pcb_coord_t *x, pcb_coord_t *y) -{ - excellon_fill_polygon_offs(gc, n_coords, x, y, 0, 0); -} - - -static void excellon_fill_rect(pcb_hid_gc_t gc, pcb_coord_t x1, pcb_coord_t y1, pcb_coord_t x2, pcb_coord_t y2) -{ - excellon_fill_polygon(gc, 0, NULL, NULL); -} - -static void excellon_calibrate(double xval, double yval) -{ - pcb_message(PCB_MSG_ERROR, "Excellon internal error: can not calibrate()\n"); -} - -static int excellon_usage(const char *topic) -{ - fprintf(stderr, "\nexcellon exporter command line arguments:\n\n"); - pcb_hid_usage(excellon_options, sizeof(excellon_options) / sizeof(excellon_options[0])); - fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x excellon [excellon options] foo.pcb\n\n"); - return 0; -} - -static void excellon_set_crosshair(pcb_coord_t x, pcb_coord_t y, int action) -{ -} - - - -int pplg_check_ver_export_excellon(int ver_needed) { return 0; } - -void pplg_uninit_export_excellon(void) -{ - pcb_hid_remove_attributes_by_cookie(excellon_cookie); - free(filename); -} - -int pplg_init_export_excellon(void) -{ - PCB_API_CHK_VER; - - memset(&excellon_hid, 0, sizeof(excellon_hid)); - - pcb_hid_nogui_init(&excellon_hid); - pcb_dhlp_draw_helpers_init(&excellon_hid); - - excellon_hid.struct_size = sizeof(excellon_hid); - excellon_hid.name = "excellon"; - excellon_hid.description = "excellon drill/boundary export"; - excellon_hid.exporter = 1; - - excellon_hid.get_export_options = excellon_get_export_options; - excellon_hid.do_export = excellon_do_export; - excellon_hid.parse_arguments = excellon_parse_arguments; - excellon_hid.set_layer_group = excellon_set_layer_group; - excellon_hid.make_gc = excellon_make_gc; - excellon_hid.destroy_gc = excellon_destroy_gc; - excellon_hid.set_drawing_mode = excellon_set_drawing_mode; - excellon_hid.set_color = excellon_set_color; - excellon_hid.set_line_cap = excellon_set_line_cap; - excellon_hid.set_line_width = excellon_set_line_width; - excellon_hid.set_draw_xor = excellon_set_draw_xor; - excellon_hid.draw_line = excellon_draw_line; - excellon_hid.draw_arc = excellon_draw_arc; - excellon_hid.draw_rect = excellon_draw_rect; - excellon_hid.fill_circle = excellon_fill_circle; - excellon_hid.fill_polygon = excellon_fill_polygon; - excellon_hid.fill_polygon_offs = excellon_fill_polygon_offs; - excellon_hid.fill_rect = excellon_fill_rect; - excellon_hid.calibrate = excellon_calibrate; - excellon_hid.set_crosshair = excellon_set_crosshair; - excellon_hid.usage = excellon_usage; - - pcb_hid_register_hid(&excellon_hid); - return 0; -} Index: trunk/src_plugins/export_gerber/excellon.h =================================================================== --- trunk/src_plugins/export_gerber/excellon.h (revision 24871) +++ trunk/src_plugins/export_gerber/excellon.h (nonexistent) @@ -1,12 +0,0 @@ -#ifndef PCB_DRILL_H -#define PCB_DRILL_H - -#include "aperture.h" - -void pcb_drill_export_excellon(pcb_board_t *pcb, pcb_drill_ctx_t *ctx, int force_g85, const char *fn); - -int pplg_check_ver_export_excellon(int ver_needed); -void pplg_uninit_export_excellon(void); -int pplg_init_export_excellon(void); - -#endif Index: trunk/src_plugins/export_gerber/Plug.tmpasm =================================================================== --- trunk/src_plugins/export_gerber/Plug.tmpasm (revision 24871) +++ trunk/src_plugins/export_gerber/Plug.tmpasm (revision 24872) @@ -1,8 +1,6 @@ put /local/pcb/mod {export_gerber} put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_gerber/gerber.o - $(PLUGDIR)/export_gerber/aperture.o - $(PLUGDIR)/export_gerber/excellon.o @] put /local/pcb/mod/CONF {$(PLUGDIR)/export_gerber/gerber_conf.h} Index: trunk/src_plugins/export_gerber/export_gerber.pup =================================================================== --- trunk/src_plugins/export_gerber/export_gerber.pup (revision 24871) +++ trunk/src_plugins/export_gerber/export_gerber.pup (revision 24872) @@ -5,5 +5,6 @@ $fmt-native no $fmt-feature-w export gerber for PCB fabbing, multiple files (configurable) $package export +dep export_excellon default buildin autoload 1 Index: trunk/src_plugins/export_gerber/gerber.c =================================================================== --- trunk/src_plugins/export_gerber/gerber.c (revision 24871) +++ trunk/src_plugins/export_gerber/gerber.c (revision 24872) @@ -36,8 +36,8 @@ #include "hid_inlines.h" #include "conf_core.h" -#include "aperture.h" -#include "excellon.h" +#include "../src_plugins/export_excellon/aperture.h" +#include "../src_plugins/export_excellon/excellon.h" const char *gerber_cookie = "gerber HID"; @@ -1325,7 +1325,6 @@ { pcb_hid_remove_attributes_by_cookie(gerber_cookie); conf_unreg_fields("plugins/export_gerber/"); - pplg_uninit_export_excellon(); } int pplg_init_export_gerber(void) @@ -1371,6 +1370,6 @@ gerber_hid.usage = gerber_usage; pcb_hid_register_hid(&gerber_hid); - return pplg_init_export_excellon(); + return 0; } Index: trunk/src_plugins/export_gerber/gerber_conf.h =================================================================== --- trunk/src_plugins/export_gerber/gerber_conf.h (revision 24871) +++ trunk/src_plugins/export_gerber/gerber_conf.h (revision 24872) @@ -6,8 +6,8 @@ typedef struct { const struct plugins { const struct export_gerber { - CFT_BOOLEAN plated_g85_slot; /* use G85 (drill cycle instead of route) for plated slots */ - CFT_BOOLEAN unplated_g85_slot; /* use G85 (drill cycle instead of route) for unplated slots */ + CFT_BOOLEAN plated_g85_slot; /* use G85 (drill cycle instead of route) for plated slots - only affects direct gerber export, DO NOT USE, check excellon's config instead */ + CFT_BOOLEAN unplated_g85_slot; /* use G85 (drill cycle instead of route) for unplated slots - only affects direct gerber export, DO NOT USE, check excellon's config instead */ } export_gerber; } plugins; } conf_gerber_t; Index: trunk/src_plugins/plugins_ALL.tmpasm =================================================================== --- trunk/src_plugins/plugins_ALL.tmpasm (revision 24871) +++ trunk/src_plugins/plugins_ALL.tmpasm (revision 24872) @@ -22,6 +22,7 @@ include {../src_plugins/export_bom/Plug.tmpasm} include {../src_plugins/export_dsn/Plug.tmpasm} include {../src_plugins/export_dxf/Plug.tmpasm} +include {../src_plugins/export_excellon/Plug.tmpasm} include {../src_plugins/export_fidocadj/Plug.tmpasm} include {../src_plugins/export_gcode/Plug.tmpasm} include {../src_plugins/export_gerber/Plug.tmpasm}