Index: trunk/src_plugins/io_pads/write.c =================================================================== --- trunk/src_plugins/io_pads/write.c (revision 34642) +++ trunk/src_plugins/io_pads/write.c (revision 34643) @@ -31,6 +31,8 @@ #include +#include +#include #include #include @@ -41,10 +43,16 @@ FILE *f; pcb_board_t *pcb; double ver; + + /* layer mapping */ + vti0_t gid2plid; /* group ID to pads layer ID */ + vtp0_t plid2grp; /* pads layer ID to pcb-rnd group */ } write_ctx_t; #define CRD(c) ((long)rnd_round(RND_COORD_TO_MM(c) * 10000)) +#include "write_layer.c" + static int pads_write_blk_pcb(write_ctx_t *wctx) { int coplyn; @@ -149,7 +157,8 @@ static int io_pads_write_pcb(pcb_plug_io_t *ctx, FILE *f, const char *old_filename, const char *new_filename, rnd_bool emergency, double ver) { - write_ctx_t wctx; + write_ctx_t wctx = {0}; + int res; wctx.f = f; wctx.pcb = PCB; @@ -157,7 +166,11 @@ fprintf(f, "!PADS-POWERPCB-V%.1f-METRIC! DESIGN DATABASE ASCII FILE 1.0\r\n", ver); - return pads_write_pcb_(&wctx); + pads_map_layers(&wctx); + res = pads_write_pcb_(&wctx); + pads_free_layers(&wctx); + + return res; } int io_pads_write_pcb_2005(pcb_plug_io_t *ctx, FILE *f, const char *old_filename, const char *new_filename, rnd_bool emergency) Index: trunk/src_plugins/io_pads/write_layer.c =================================================================== --- trunk/src_plugins/io_pads/write_layer.c (nonexistent) +++ trunk/src_plugins/io_pads/write_layer.c (revision 34643) @@ -0,0 +1,69 @@ +typedef struct pads_lyt_map_s { + int plid; /* pads side layer ID */ + const char *purpose; + pcb_layer_type_t lyt; +} pads_lyt_map_t; + +static const pads_lyt_map_t pads_lyt_map[] = { + {21, NULL, PCB_LYT_TOP | PCB_LYT_MASK}, + {22, NULL, PCB_LYT_BOTTOM | PCB_LYT_PASTE}, + {23, NULL, PCB_LYT_TOP | PCB_LYT_PASTE}, + /*{24, NULL, PCB_LYT_FAB},*/ + {26, NULL, PCB_LYT_TOP | PCB_LYT_SILK}, + {27, "assy", PCB_LYT_TOP | PCB_LYT_DOC}, + {28, NULL, PCB_LYT_BOTTOM | PCB_LYT_MASK}, + {29, NULL, PCB_LYT_BOTTOM | PCB_LYT_SILK}, + {30, "assy", PCB_LYT_BOTTOM | PCB_LYT_DOC}, + {0, NULL, 0} +}; + +#define FIRST_DOC_PLID 31 + +static void pads_map_layers(write_ctx_t *wctx) +{ + pcb_layergrp_t *g; + rnd_layergrp_id_t gid; + int copnext = 1, docnext = FIRST_DOC_PLID; + + vti0_set(&wctx->gid2plid, 64, 0); /* enlarge to save on reallocs */ + vtp0_set(&wctx->plid2grp, wctx->pcb->LayerGroups.len, 0); /* enlarge to save on reallocs */ + for(gid = 0, g = wctx->pcb->LayerGroups.grp; gid < wctx->pcb->LayerGroups.len; gid++,g++) { + if (g->ltype & PCB_LYT_SUBSTRATE) + continue; + if (g->ltype & PCB_LYT_COPPER) { + vti0_set(&wctx->gid2plid, gid, copnext); + vtp0_set(&wctx->plid2grp, copnext, g); + copnext++; + } + else { /* non-copper */ + pads_lyt_map_t *m; + + for(m = pads_lyt_map; m->plid != NULL; m++) + if (((g->ltype & m->lyt) == m->lyt) && ((m->purpose == NULL) || (strcmp(m->purpose, g->purpose) == 0))) + break; + + if (m->plid != 0) { + vti0_set(&wctx->gid2plid, gid, m->plid); + if (wctx->plid2grp.array[m->plid] != NULL) { + pcb_layergrp_t *e = wctx->plid2grp.array[m->plid]; + char *tmp = rnd_strdup_printf("Multiple non-copper layer groups with the same type: '%s' and '%s'\n", e->name, g->name); + pcb_io_incompat_save(wctx->pcb->Data, NULL, "layer-grp", tmp, "These layer groups will be merged in PADS ASCII"); + } + else + vtp0_set(&wctx->plid2grp, m->plid, g); + } + else { /* no match */ + vti0_set(&wctx->gid2plid, gid, docnext); + vtp0_set(&wctx->plid2grp, docnext, g); + docnext++; + } + } + } +} + +static void pads_free_layers(write_ctx_t *wctx) +{ + vti0_uninit(&wctx->gid2plid); + vtp0_uninit(&wctx->plid2grp); +} +