Index: trunk/src_plugins/io_pads/write.c =================================================================== --- trunk/src_plugins/io_pads/write.c (revision 34650) +++ trunk/src_plugins/io_pads/write.c (revision 34651) @@ -193,6 +193,7 @@ if (pads_write_blk_reuse(wctx) != 0) return -1; if (pads_write_blk_text(wctx) != 0) return -1; + if (pads_write_blk_misc_layers(wctx) != 0) return -1; return -1; } Index: trunk/src_plugins/io_pads/write_layer.c =================================================================== --- trunk/src_plugins/io_pads/write_layer.c (revision 34650) +++ trunk/src_plugins/io_pads/write_layer.c (revision 34651) @@ -19,11 +19,18 @@ #define FIRST_DOC_PLID 31 +static int pads_max_plid(write_ctx_t *wctx) +{ + if ((wctx->ver >= 9.0) && (wctx->ver < 1000)) + return 250; + return 30; +} + 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; + int copnext = 1, docnext = FIRST_DOC_PLID, maxplid = pads_max_plid(wctx); 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 */ @@ -31,14 +38,21 @@ 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++; + if (copnext <= 20) { + vti0_set(&wctx->gid2plid, gid, copnext); + vtp0_set(&wctx->plid2grp, copnext, g); + copnext++; + } + else { + char *tmp = rnd_strdup_printf("Too many copper layers; not exporting layer group '%s'\n", g->name); + pcb_io_incompat_save(wctx->pcb->Data, NULL, "layer-grp", tmp, "At the moment only 20 copper layers are supported on PADSC ASCII export. If you bump into this limitation, please contact pcb-rnd developers."); + free(tmp); + } } else { /* non-copper */ - pads_lyt_map_t *m; + const pads_lyt_map_t *m; - for(m = pads_lyt_map; m->plid != NULL; m++) + for(m = pads_lyt_map; m->plid != 0; m++) if (((g->ltype & m->lyt) == m->lyt) && ((m->purpose == NULL) || (strcmp(m->purpose, g->purpose) == 0))) break; @@ -48,14 +62,22 @@ 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"); + free(tmp); } else vtp0_set(&wctx->plid2grp, m->plid, g); } else { /* no match */ - vti0_set(&wctx->gid2plid, gid, docnext); - vtp0_set(&wctx->plid2grp, docnext, g); - docnext++; + if (docnext <= maxplid) { + vti0_set(&wctx->gid2plid, gid, docnext); + vtp0_set(&wctx->plid2grp, docnext, g); + docnext++; + } + else { + char *tmp = rnd_strdup_printf("Too many non-copper layers; not exporting layer group '%s'\n", g->name); + pcb_io_incompat_save(wctx->pcb->Data, NULL, "layer-grp", tmp, "This version of PADS ASCII supports 30 layers only. Choose a newer version to have the 250 layer mode."); + free(tmp); + } } } } @@ -73,6 +95,74 @@ return pads_gid2plid(wctx, pcb_layer_get_group_(l)); } +static int pads_write_blk_misc_layers(write_ctx_t *wctx) +{ + int plid, max_plid; + + fprintf(wctx->f, "*MISC* MISCELLANEOUS PARAMETERS\r\n\r\n"); + fprintf(wctx->f, "*REMARK* PARENT_KEYWORD PARENT_VALUE\r\n"); + fprintf(wctx->f, "*REMARK* [ {\r\n"); + fprintf(wctx->f, "*REMARK* CHILD_KEYWORD CHILD_VALUE\r\n"); + fprintf(wctx->f, "*REMARK* [ CHILD_KEYWORD CHILD_VALUE\r\n"); + fprintf(wctx->f, "*REMARK* [ {\r\n"); + fprintf(wctx->f, "*REMARK* GRAND_CHILD_KEYWORD GRAND_CHILD_VALUE [...]\r\n"); + fprintf(wctx->f, "*REMARK* } ]]\r\n"); + fprintf(wctx->f, "*REMARK* } ]\r\n\r\n"); + fprintf(wctx->f, "LAYER DATA\r\n"); + fprintf(wctx->f, "{\r\n"); + fprintf(wctx->f, "LAYER 0\r\n"); + fprintf(wctx->f, "{\r\n"); + fprintf(wctx->f, "LAYER_THICKNESS 0\r\n"); + fprintf(wctx->f, "DIELECTRIC 3.300000\r\n"); + fprintf(wctx->f, "}\r\n"); + + max_plid = pads_max_plid(wctx); + + for(plid = 0; plid <= max_plid; plid++) { + pcb_layergrp_t *g = NULL; + + if (plid < wctx->plid2grp.used) + g = wctx->plid2grp.array[plid]; + + fprintf(wctx->f, "LAYER %d\r\n", plid); + fprintf(wctx->f, "{\r\n"); + + if (g != NULL) { + fprintf(wctx->f, "LAYER_NAME %s\r\n", g->name); + + if (g->ltype & PCB_LYT_COPPER) fprintf(wctx->f, "LAYER_TYPE ROUTING\r\n"); + else if (g->ltype & PCB_LYT_SILK) fprintf(wctx->f, "LAYER_TYPE SILK_SCREEN\r\n"); + else if (g->ltype & PCB_LYT_PASTE) fprintf(wctx->f, "LAYER_TYPE PASTE_MASK\r\n"); + else if (g->ltype & PCB_LYT_MASK) fprintf(wctx->f, "LAYER_TYPE SOLDER_MASK\r\n"); + else goto unassigned; +/* ASSOCIATED_SILK_SCREEN Silkscreen Top + ASSOCIATED_PASTE_MASK Paste Mask Top + ASSOCIATED_SOLDER_MASK Solder Mask Top + ASSOCIATED_ASSEMBLY Assembly Drawing Top +*/ + } + else { + fprintf(wctx->f, "LAYER_NAME Layer_%d\r\n", plid); + unassigned:; + fprintf(wctx->f, "LAYER_TYPE UNASSIGNED\r\n"); + } + + fprintf(wctx->f, "PLANE NONE\r\n"); + fprintf(wctx->f, "ROUTING_DIRECTION NO_PREFERENCE\r\n"); + fprintf(wctx->f, "VISIBLE Y\r\n"); + fprintf(wctx->f, "SELECTABLE Y\r\n"); + fprintf(wctx->f, "ENABLED Y\r\n"); + fprintf(wctx->f, "LAYER_THICKNESS 0\r\n"); + fprintf(wctx->f, "COPPER_THICKNESS 0\r\n"); + fprintf(wctx->f, "DIELECTRIC 0.000000\r\n"); + fprintf(wctx->f, "COST 0\r\n"); + fprintf(wctx->f, "}\r\n"); + } + + fprintf(wctx->f, "}\r\n\r\n"); + return 0; +} + static void pads_free_layers(write_ctx_t *wctx) { vti0_uninit(&wctx->gid2plid);