diff -C 3 -r pcb-20080202/doc/pcb.texi pcb-20080202-stefan_BA-20080703/doc/pcb.texi *** pcb-20080202/doc/pcb.texi Sat Jul 5 15:38:15 2008 --- pcb-20080202-stefan_BA-20080703/doc/pcb.texi Sat Jul 5 15:38:15 2008 *************** *** 280,286 **** @section Vias @cindex vias, an overview ! Vias provide through-hole connectivity across all layers. While vias look a lot like element pins, don't use vias for adding elements to the layout, even if that seems easier than creating a new element. The default solder-mask --- 280,286 ---- @section Vias @cindex vias, an overview ! Vias provide through-hole connectivity across layers. While vias look a lot like element pins, don't use vias for adding elements to the layout, even if that seems easier than creating a new element. The default solder-mask *************** *** 294,301 **** a via switches it between being a pure-mounting hole and a regular via. You can assign a name to a via, which is useful during the creation of new element definitions. ! Each via exists on all copper layers. (@emph{i.e.} ! blind and buried vias are not supported) @node Element Objects --- 294,304 ---- a via switches it between being a pure-mounting hole and a regular via. You can assign a name to a via, which is useful during the creation of new element definitions. ! The layers a via exists on is determined by the layer visibility ! at the time of via creation. To creat a standard via that connects ! all layers, ensure that all layers are visible when creating the via. ! It is possible to create blind and buried vias by making only those ! layers visible the via shall exist on and then creating the via. @node Element Objects diff -C 3 -r pcb-20080202/src/action.c pcb-20080202-stefan_BA-20080703/src/action.c *** pcb-20080202/src/action.c Sat Jul 5 15:38:10 2008 --- pcb-20080202-stefan_BA-20080703/src/action.c Sat Jul 5 15:38:15 2008 *************** *** 999,1004 **** --- 999,1005 ---- case VIA_MODE: { PinTypePtr via; + int i; if (!PCB->ViaOn) { *************** *** 1012,1017 **** --- 1013,1020 ---- NoFlags ())) != NULL) { AddObjectToCreateUndoList (VIA_TYPE, via, via, via); + for (i = 0; i < max_layer; i++) /* disable via on all layers currently invisible */ + ASSIGN_DISAB_LAY (i, !LAYER_PTR(i)->On, via); if (gui->shift_is_pressed ()) ChangeObjectThermal (VIA_TYPE, via, via, via, PCB->ThermStyle); IncrementUndoSerialNumber (); diff -C 3 -r pcb-20080202/src/draw.c pcb-20080202-stefan_BA-20080703/src/draw.c *** pcb-20080202/src/draw.c Sat Jul 5 15:38:10 2008 --- pcb-20080202-stefan_BA-20080703/src/draw.c Sat Jul 5 15:38:15 2008 *************** *** 113,118 **** --- 113,119 ---- static void DrawRats (BoxType *); static void DrawSilk (int, int, BoxType *); static int pin_callback (const BoxType * b, void *cl); + static int pin_via_callback (const BoxType * b, void *cl); static int pad_callback (const BoxType * b, void *cl); /*-------------------------------------------------------------------------------------- *************** *** 304,315 **** return 0; } static int hole_callback (const BoxType * b, void *cl) { PinTypePtr pin = (PinTypePtr) b; ! int plated = cl ? *(int *) cl : -1; ! switch (plated) { case -1: break; --- 305,368 ---- return 0; } + enum via_mode { + via_on_current, /* draw (holes of) vias enabled on current layer */ + via_on_visible, /* draw (holes of) vias enabled on any visble layer */ + via_on_all, /* draw (holes of) vias enabled on all layers */ + via_all, /* draw all (holes of) vias */ + via_by_hole_type, /* draw (holes of) vias with specified hole type */ + }; + + typedef struct + { + unsigned char dl[(MAX_LAYER + 7) >> 3]; /* hole type == dl member of object flags */ + } HoleType; + + struct hole_info { + int plated; /* -1: draw all holes, 0: draw ony unplated holes, 1: draw only plated holes */ + enum via_mode via_m; /* for holes of vias */ + HoleType hole_type; /* the hole type to draw (for via_m == via_by_hole_type) */ + }; + + static int check_draw_via (const PinTypePtr via, enum via_mode via_m, const HoleType * hole_type /* may be NULL */) + { + switch (via_m) { + case via_on_current: /* only (holes of) vias enabled on current layer */ + if (TEST_DISAB_LAY(INDEXOFCURRENT, via)) + return 0; /* do not draw */ + return 1; /* draw */ + case via_on_visible: /* only (holes of) vias enabled on any visible layer */ + { + int i; + for (i = 0; i < max_layer; i++) + if (LAYER_PTR(i)->On && !TEST_DISAB_LAY(i, via)) + break; + if (i >= max_layer) + return 0; /* do not draw */ + } + return 1; /* draw */ + case via_on_all: /* only (holes of) vias on all layers */ + if (TEST_ANY_DISAB_LAY(via)) + return 0; /* do not draw */ + return 1; /* draw */ + case via_all: /* (holes of) all vias */ + return 1; /* draw */ + case via_by_hole_type: /* draw (holes of) vias with specified hole type */ + if (hole_type == NULL || memcmp(via->Flags.dl, hole_type, sizeof( HoleType )) != 0) + return 0; /* do not draw */ + return 1; /* draw */ + } + return 1; /* draw */ + } + static int hole_callback (const BoxType * b, void *cl) { PinTypePtr pin = (PinTypePtr) b; ! struct hole_info * hole_i = (struct hole_info *)cl; ! if (!check_draw_via (pin, hole_i->via_m, &hole_i->hole_type)) ! return 1; ! switch (hole_i->plated) { case -1: break; *************** *** 328,335 **** --- 381,395 ---- typedef struct { + int cnt; /* number of hole types in list */ + HoleType list[16]; /* list with hole types */ + } HoleTypeList; + + typedef struct + { int nplated; int nunplated; + HoleTypeList hole_types; /* hole types of plated holes */ } HoleCountStruct; static int *************** *** 337,346 **** --- 397,426 ---- { PinTypePtr pin = (PinTypePtr) b; HoleCountStruct *hcs = (HoleCountStruct *) cl; + int i; + + /* count plated and unplated holes */ if (TEST_FLAG (HOLEFLAG, pin)) hcs->nunplated++; else hcs->nplated++; + + /* collect all hole types for plated holes */ + if (!TEST_FLAG (HOLEFLAG, pin)) { + /* search hole type in list */ + for( i = 0; i < hcs->hole_types.cnt; i++ ) + if( memcmp( &pin->Flags.dl, &hcs->hole_types.list[i], sizeof( HoleType ) ) == 0 ) + break; /* found hole type in list */ + /* not found */ + if( i >= hcs->hole_types.cnt ) { + /* add hole type to list */ + if( hcs->hole_types.cnt < sizeof( hcs->hole_types.list ) / sizeof( hcs->hole_types.list[0] ) ) { /* ignore if list is full */ + memcpy( &hcs->hole_types.list[hcs->hole_types.cnt], &pin->Flags.dl, sizeof( HoleType ) ); + hcs->hole_types.cnt++; + } + } + } + return 1; } *************** *** 351,360 **** --- 431,447 ---- return 1; } + struct via_info { + enum via_mode via_m; + }; + static int lowvia_callback (const BoxType * b, void *cl) { PinTypePtr via = (PinTypePtr) b; + struct via_info * via_i = (struct via_info *)cl; + if (!check_draw_via (via, via_i->via_m, NULL)) + return 1; if (!via->Mask) DrawPlainVia (via, False); return 1; *************** *** 368,378 **** PrintAssembly (const BoxType * drawn_area, int side_group, int swap_ident) { int save_swap = SWAP_IDENT; gui->set_draw_faded (Output.fgGC, 1); SWAP_IDENT = swap_ident; DrawLayerGroup (side_group, drawn_area); ! r_search (PCB->Data->via_tree, drawn_area, NULL, lowvia_callback, NULL); DrawTop (drawn_area); gui->set_draw_faded (Output.fgGC, 0); --- 455,467 ---- PrintAssembly (const BoxType * drawn_area, int side_group, int swap_ident) { int save_swap = SWAP_IDENT; + struct via_info via_i; gui->set_draw_faded (Output.fgGC, 1); SWAP_IDENT = swap_ident; DrawLayerGroup (side_group, drawn_area); ! via_i.via_m = via_all; ! r_search (PCB->Data->via_tree, drawn_area, NULL, lowvia_callback, &via_i); DrawTop (drawn_area); gui->set_draw_faded (Output.fgGC, 0); *************** *** 383,388 **** --- 472,486 ---- SWAP_IDENT = save_swap; } + struct pin_via_info { + int group; + }; + + static int hole_type_cmp (const void * a, const void * b) + { + return memcmp (a, b, sizeof( HoleType )); + } + /* --------------------------------------------------------------------------- * initializes some identifiers for a new zoom factor and redraws whole screen */ *************** *** 390,401 **** DrawEverything (BoxTypePtr drawn_area) { int i, ngroups, side; - int plated; int component, solder; /* This is the list of layer groups we will draw. */ int do_group[MAX_LAYER]; /* This is the reverse of the order in which we draw them. */ int drawn_groups[MAX_LAYER]; PCB->Data->SILKLAYER.Color = PCB->ElementColor; PCB->Data->BACKSILKLAYER.Color = PCB->InvisibleObjectsColor; --- 488,501 ---- DrawEverything (BoxTypePtr drawn_area) { int i, ngroups, side; int component, solder; /* This is the list of layer groups we will draw. */ int do_group[MAX_LAYER]; /* This is the reverse of the order in which we draw them. */ int drawn_groups[MAX_LAYER]; + struct via_info via_i; + struct hole_info hole_i; + struct pin_via_info pin_via_i; PCB->Data->SILKLAYER.Color = PCB->ElementColor; PCB->Data->BACKSILKLAYER.Color = PCB->InvisibleObjectsColor; *************** *** 433,438 **** --- 533,547 ---- } } + /* draw vias enabled in any visible layer */ + if (PCB->ViaOn && gui->gui) { + via_i.via_m = via_on_visible; + hole_i.plated = -1; + hole_i.via_m = via_on_visible; + r_search (PCB->Data->via_tree, drawn_area, NULL, lowvia_callback, &via_i); + r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, &hole_i); + } + /* draw all layers in layerstack order */ for (i = ngroups - 1; i >= 0; i--) { *************** *** 448,455 **** continue; r_search (PCB->Data->pin_tree, drawn_area, NULL, pin_callback, NULL); ! r_search (PCB->Data->via_tree, drawn_area, NULL, pin_callback, ! NULL); /* draw element pads */ if (group == component || group == solder) { --- 557,565 ---- continue; r_search (PCB->Data->pin_tree, drawn_area, NULL, pin_callback, NULL); ! pin_via_i.group = group; ! r_search (PCB->Data->via_tree, drawn_area, NULL, pin_via_callback, ! &pin_via_i); /* draw element pads */ if (group == component || group == solder) { *************** *** 462,472 **** if (!gui->gui) { /* draw holes */ ! plated = -1; r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, ! &plated); r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, ! &plated); } } } --- 572,583 ---- if (!gui->gui) { /* draw holes */ ! hole_i.plated = -1; ! hole_i.via_m = via_on_current; r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, ! &hole_i); r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, ! &hole_i); } } } *************** *** 474,482 **** if (TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->gui) return; ! /* draw vias below silk */ if (PCB->ViaOn && gui->gui) ! r_search (PCB->Data->via_tree, drawn_area, NULL, lowvia_callback, NULL); /* Draw the solder mask if turned on */ if (gui->set_layer ("componentmask", SL (MASK, TOP))) { --- 585,594 ---- if (TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->gui) return; ! /* draw vias enabled in current layer below silk */ ! via_i.via_m = via_on_current; if (PCB->ViaOn && gui->gui) ! r_search (PCB->Data->via_tree, drawn_area, NULL, lowvia_callback, &via_i); /* Draw the solder mask if turned on */ if (gui->set_layer ("componentmask", SL (MASK, TOP))) { *************** *** 497,523 **** DrawTop (drawn_area); else { HoleCountStruct hcs; hcs.nplated = hcs.nunplated = 0; r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_counting_callback, &hcs); r_search (PCB->Data->via_tree, drawn_area, NULL, hole_counting_callback, &hcs); ! if (hcs.nplated && gui->set_layer ("plated-drill", SL (PDRILL, 0))) ! { ! plated = 1; ! r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, ! &plated); ! r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, ! &plated); } if (hcs.nunplated && gui->set_layer ("unplated-drill", SL (UDRILL, 0))) { ! plated = 0; r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, ! &plated); r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, ! &plated); } } /* Draw top silkscreen */ --- 609,661 ---- DrawTop (drawn_area); else { + /* count holes and get hole types */ HoleCountStruct hcs; hcs.nplated = hcs.nunplated = 0; + hcs.hole_types.cnt = 0; r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_counting_callback, &hcs); r_search (PCB->Data->via_tree, drawn_area, NULL, hole_counting_callback, &hcs); ! /* sort holes */ ! qsort (hcs.hole_types.list, hcs.hole_types.cnt, sizeof( HoleType ), hole_type_cmp); ! if (hcs.nplated) ! { ! int hole_type_idx; ! for (hole_type_idx = 0; hole_type_idx < hcs.hole_types.cnt; hole_type_idx++) /* draw all hole types separately */ ! { ! HoleType hole_type = hcs.hole_types.list[hole_type_idx]; ! /* get name for current hole type */ ! char name[32]; ! int number; ! if (mem_any_set( hole_type.dl, sizeof( hole_type.dl ))) { ! sprintf( name, "special-plated-drill-%d", hole_type_idx ); /* special plated drill (i.e. blind or buried vias) */ ! number = SLNO (SPDRILL, 0, hole_type_idx); ! } else { ! strcpy( name, "plated-drill" ); /* normal plated drill */ ! number = SL (PDRILL, 0); ! } ! /* set layer and draw holes */ ! if (gui->set_layer (name, number)) ! { ! hole_i.plated = 1; ! hole_i.via_m = via_by_hole_type; ! hole_i.hole_type = hole_type; ! r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, ! &hole_i); ! r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, ! &hole_i); ! } ! } } if (hcs.nunplated && gui->set_layer ("unplated-drill", SL (UDRILL, 0))) { ! hole_i.plated = 0; ! hole_i.via_m = via_all; r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, ! &hole_i); r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, ! &hole_i); } } /* Draw top silkscreen */ *************** *** 625,630 **** --- 763,771 ---- via_callback (const BoxType * b, void *cl) { PinTypePtr via = (PinTypePtr) b; + struct via_info * via_i = (struct via_info *)cl; + if (!check_draw_via (via, via_i->via_m, NULL)) + return 1; if (via->Mask) DrawPlainVia (via, False); return 1; *************** *** 637,642 **** --- 778,794 ---- return 1; } + /* special version of pin_callback for vias + * used to only draw vias enabled on one layer of the group + */ + static int pin_via_callback (const BoxType * b, void *cl) + { + struct pin_via_info * pin_via_i = (struct pin_via_info *)cl; + if (! TEST_DISAB_LAY(pin_via_i->group, (PinTypePtr) b)) + DrawPlainPin ((PinTypePtr) b, False); + return 1; + } + static int pad_callback (const BoxType * b, void *cl) { *************** *** 652,657 **** --- 804,811 ---- static void DrawTop (const BoxType * screen) { + struct via_info via_i; + struct hole_info hole_i; if (PCB->PinOn || doing_assy) { /* draw element pins */ *************** *** 660,672 **** r_search (PCB->Data->pad_tree, screen, NULL, pad_callback, NULL); } /* draw vias */ if (PCB->ViaOn || doing_assy) { ! r_search (PCB->Data->via_tree, screen, NULL, via_callback, NULL); ! r_search (PCB->Data->via_tree, screen, NULL, hole_callback, NULL); } if (PCB->PinOn || doing_assy) ! r_search (PCB->Data->pin_tree, screen, NULL, hole_callback, NULL); } struct pin_info --- 814,829 ---- r_search (PCB->Data->pad_tree, screen, NULL, pad_callback, NULL); } /* draw vias */ + via_i.via_m = via_on_current; + hole_i.plated = -1; + hole_i.via_m = via_on_current; if (PCB->ViaOn || doing_assy) { ! r_search (PCB->Data->via_tree, screen, NULL, via_callback, &via_i); ! r_search (PCB->Data->via_tree, screen, NULL, hole_callback, &hole_i); } if (PCB->PinOn || doing_assy) ! r_search (PCB->Data->pin_tree, screen, NULL, hole_callback, &hole_i); } struct pin_info diff -C 3 -r pcb-20080202/src/find.c pcb-20080202-stefan_BA-20080703/src/find.c *** pcb-20080202/src/find.c Sat Jul 5 15:38:10 2008 --- pcb-20080202-stefan_BA-20080703/src/find.c Sat Jul 5 15:38:15 2008 *************** *** 649,658 **** PadTypePtr pad = (PadTypePtr) b; struct pv_info *i = (struct pv_info *) cl; ! if (!TEST_FLAG (TheFlag, pad) && IS_PV_ON_PAD (&i->pv, pad) && ! ADD_PAD_TO_LIST (TEST_FLAG (ONSOLDERFLAG, pad) ? SOLDER_LAYER : ! COMPONENT_LAYER, pad)) ! longjmp (i->env, 1); return 0; } --- 649,662 ---- PadTypePtr pad = (PadTypePtr) b; struct pv_info *i = (struct pv_info *) cl; ! int sc_layer = TEST_FLAG (ONSOLDERFLAG, pad) ? SOLDER_LAYER : COMPONENT_LAYER; ! int layer = GetLayerGroupNumberByNumber (max_layer + sc_layer); ! ! if (!TEST_DISAB_LAY (layer, &i->pv)) { ! if (!TEST_FLAG (TheFlag, pad) && IS_PV_ON_PAD (&i->pv, pad) && ! ADD_PAD_TO_LIST (sc_layer, pad)) ! longjmp (i->env, 1); ! } return 0; } *************** *** 673,688 **** PolygonTypePtr polygon = (PolygonTypePtr) b; struct pv_info *i = (struct pv_info *) cl; /* if the pin doesn't have a therm and polygon is clearing * then it can't touch due to clearance, so skip the expensive * test. If it does have a therm, you still need to test * because it might not be inside the polygon, or it could * be on an edge such that it doesn't actually touch. */ ! if (!TEST_FLAG (TheFlag, polygon) && (TEST_THERM (i->layer, &i->pv) ! || !TEST_FLAG (CLEARPOLYFLAG, ! polygon) ! || !i->pv.Clearance)) { float wide = 0.5 * i->pv.Thickness + fBloat; wide = MAX (wide, 0); --- 677,697 ---- PolygonTypePtr polygon = (PolygonTypePtr) b; struct pv_info *i = (struct pv_info *) cl; + /* if the via is disabled for the layer it can't touch, + * so skip the expensive test. + */ /* if the pin doesn't have a therm and polygon is clearing * then it can't touch due to clearance, so skip the expensive * test. If it does have a therm, you still need to test * because it might not be inside the polygon, or it could * be on an edge such that it doesn't actually touch. */ ! if (!TEST_FLAG (TheFlag, polygon) ! && !TEST_DISAB_LAY (i->layer, &i->pv) ! && (TEST_THERM (i->layer, &i->pv) ! || !TEST_FLAG (CLEARPOLYFLAG, ! polygon) ! || !i->pv.Clearance)) { float wide = 0.5 * i->pv.Thickness + fBloat; wide = MAX (wide, 0); *************** *** 738,762 **** /* now all lines, arcs and polygons of the several layers */ for (layer = 0; layer < max_layer; layer++) { ! info.layer = layer; ! /* add touching lines */ ! if (setjmp (info.env) == 0) ! r_search (LAYER_PTR (layer)->line_tree, (BoxType *) & info.pv, ! NULL, LOCtoPVline_callback, &info); ! else ! return True; ! /* add touching arcs */ ! if (setjmp (info.env) == 0) ! r_search (LAYER_PTR (layer)->arc_tree, (BoxType *) & info.pv, ! NULL, LOCtoPVarc_callback, &info); ! else ! return True; ! /* check all polygons */ ! if (setjmp (info.env) == 0) ! r_search (LAYER_PTR (layer)->polygon_tree, (BoxType *) & info.pv, ! NULL, LOCtoPVpoly_callback, &info); ! else ! return True; } /* Check for rat-lines that may intersect the PV */ if (AndRats) --- 747,775 ---- /* now all lines, arcs and polygons of the several layers */ for (layer = 0; layer < max_layer; layer++) { ! /* if the via is not diabled for this layer */ ! if (!TEST_DISAB_LAY (layer, &info.pv)) ! { ! info.layer = layer; ! /* add touching lines */ ! if (setjmp (info.env) == 0) ! r_search (LAYER_PTR (layer)->line_tree, (BoxType *) & info.pv, ! NULL, LOCtoPVline_callback, &info); ! else ! return True; ! /* add touching arcs */ ! if (setjmp (info.env) == 0) ! r_search (LAYER_PTR (layer)->arc_tree, (BoxType *) & info.pv, ! NULL, LOCtoPVarc_callback, &info); ! else ! return True; ! /* check all polygons */ ! if (setjmp (info.env) == 0) ! r_search (LAYER_PTR (layer)->polygon_tree, (BoxType *) & info.pv, ! NULL, LOCtoPVpoly_callback, &info); ! else ! return True; ! } } /* Check for rat-lines that may intersect the PV */ if (AndRats) *************** *** 899,919 **** { PinTypePtr pin = (PinTypePtr) b; struct pv_info *i = (struct pv_info *) cl; ! if (!TEST_FLAG (TheFlag, pin) && PV_TOUCH_PV (&i->pv, pin)) ! { ! if (TEST_FLAG (HOLEFLAG, pin)) ! { ! SET_FLAG (WARNFLAG, pin); ! Settings.RatWarn = True; ! if (pin->Element) ! Message (_("WARNING: Hole too close to pin.\n")); ! else ! Message (_("WARNING: Hole too close to via.\n")); ! } ! if (ADD_PV_TO_LIST (pin)) ! longjmp (i->env, 1); ! } return 0; } --- 912,941 ---- { PinTypePtr pin = (PinTypePtr) b; struct pv_info *i = (struct pv_info *) cl; + int l; ! /* find a layer both vias are enabled in */ ! for (l = 0; l < max_layer; l++) ! if (!TEST_DISAB_LAY(l, pin) && !TEST_DISAB_LAY(l, &i->pv)) ! break; ! if (l < max_layer) { ! ! if (!TEST_FLAG (TheFlag, pin) && PV_TOUCH_PV (&i->pv, pin)) ! { ! if (TEST_FLAG (HOLEFLAG, pin)) ! { ! SET_FLAG (WARNFLAG, pin); ! Settings.RatWarn = True; ! if (pin->Element) ! Message (_("WARNING: Hole too close to pin.\n")); ! else ! Message (_("WARNING: Hole too close to via.\n")); ! } ! if (ADD_PV_TO_LIST (pin)) ! longjmp (i->env, 1); ! } ! ! } return 0; } *************** *** 967,973 **** PinTypePtr pv = (PinTypePtr) b; struct lo_info *i = (struct lo_info *) cl; ! if (!TEST_FLAG (TheFlag, pv) && PinLineIntersect (pv, &i->line)) { if (TEST_FLAG (HOLEFLAG, pv)) { --- 989,997 ---- PinTypePtr pv = (PinTypePtr) b; struct lo_info *i = (struct lo_info *) cl; ! if (!TEST_FLAG (TheFlag, pv) ! && !TEST_DISAB_LAY (i->layer, pv) ! && PinLineIntersect (pv, &i->line)) { if (TEST_FLAG (HOLEFLAG, pv)) { *************** *** 987,993 **** PinTypePtr pv = (PinTypePtr) b; struct lo_info *i = (struct lo_info *) cl; ! if (!TEST_FLAG (TheFlag, pv) && IS_PV_ON_PAD (pv, &i->pad)) { if (TEST_FLAG (HOLEFLAG, pv)) { --- 1011,1022 ---- PinTypePtr pv = (PinTypePtr) b; struct lo_info *i = (struct lo_info *) cl; ! int sc_layer = TEST_FLAG (ONSOLDERFLAG, &i->pad) ? SOLDER_LAYER : COMPONENT_LAYER; ! int layer = GetLayerGroupNumberByNumber (max_layer + sc_layer); ! ! if (!TEST_FLAG (TheFlag, pv) ! && !TEST_DISAB_LAY (layer, pv) ! && IS_PV_ON_PAD (pv, &i->pad)) { if (TEST_FLAG (HOLEFLAG, pv)) { *************** *** 1007,1013 **** PinTypePtr pv = (PinTypePtr) b; struct lo_info *i = (struct lo_info *) cl; ! if (!TEST_FLAG (TheFlag, pv) && IS_PV_ON_ARC (pv, &i->arc)) { if (TEST_FLAG (HOLEFLAG, pv)) { --- 1036,1044 ---- PinTypePtr pv = (PinTypePtr) b; struct lo_info *i = (struct lo_info *) cl; ! if (!TEST_FLAG (TheFlag, pv) ! && !TEST_DISAB_LAY (i->layer, pv) ! && IS_PV_ON_ARC (pv, &i->arc)) { if (TEST_FLAG (HOLEFLAG, pv)) { *************** *** 1028,1036 **** struct lo_info *i = (struct lo_info *) cl; /* note that holes in polygons are ok */ ! if (!TEST_FLAG (TheFlag, pv) && (TEST_THERM (i->layer, pv) || ! !TEST_FLAG (CLEARPOLYFLAG, &i->polygon) || ! !pv->Clearance)) { if (TEST_FLAG (SQUAREFLAG, pv)) { --- 1059,1069 ---- struct lo_info *i = (struct lo_info *) cl; /* note that holes in polygons are ok */ ! if (!TEST_FLAG (TheFlag, pv) ! && !TEST_DISAB_LAY (i->layer, pv) ! && (TEST_THERM (i->layer, pv) || ! !TEST_FLAG (CLEARPOLYFLAG, &i->polygon) || ! !pv->Clearance)) { if (TEST_FLAG (SQUAREFLAG, pv)) { *************** *** 1095,1100 **** --- 1128,1134 ---- } /* check all lines */ + info.layer = layer; while (LineList[layer].Location < LineList[layer].Number) { info.line = *(LINELIST_ENTRY (layer, LineList[layer].Location)); *************** *** 1113,1118 **** --- 1147,1153 ---- } /* check all arcs */ + info.layer = layer; while (ArcList[layer].Location < ArcList[layer].Number) { info.arc = *(ARCLIST_ENTRY (layer, ArcList[layer].Location)); diff -C 3 -r pcb-20080202/src/global.h pcb-20080202-stefan_BA-20080703/src/global.h *** pcb-20080202/src/global.h Sat Jul 5 15:38:10 2008 --- pcb-20080202-stefan_BA-20080703/src/global.h Sat Jul 5 15:38:15 2008 *************** *** 78,83 **** --- 78,84 ---- { unsigned long f; /* generic flags */ unsigned char t[(MAX_LAYER + 1) / 2]; /* thermals */ + unsigned char dl[(MAX_LAYER + 7) >> 3]; /* disabled layers (only for vias) */ } FlagType, *FlagTypePtr; #ifndef __GNUC__ diff -C 3 -r pcb-20080202/src/hid/common/flags.c pcb-20080202-stefan_BA-20080703/src/hid/common/flags.c *** pcb-20080202/src/hid/common/flags.c Sat Jul 5 15:38:07 2008 --- pcb-20080202-stefan_BA-20080703/src/hid/common/flags.c Sat Jul 5 15:38:15 2008 *************** *** 152,158 **** { int group; ! switch (idx) { case SL (SILK, TOP): return "frontsilk"; --- 152,158 ---- { int group; ! switch (SL_REMOVE_NO (idx)) { case SL (SILK, TOP): return "frontsilk"; *************** *** 178,183 **** --- 178,189 ---- return "frontassembly"; case SL (ASSY, BOTTOM): return "backassembly"; + case SL (SPDRILL, 0): + { + static char buf[32]; + sprintf (buf, "special-plated-drill-%d", SL_NO (idx)); + return buf; + } default: group = GetLayerGroupNumberByNumber(idx); if (group == GetLayerGroupNumberByNumber(max_layer+COMPONENT_LAYER)) diff -C 3 -r pcb-20080202/src/hid/gerber/gerber.c pcb-20080202-stefan_BA-20080703/src/hid/gerber/gerber.c *** pcb-20080202/src/hid/gerber/gerber.c Sat Jul 5 15:38:07 2008 --- pcb-20080202-stefan_BA-20080703/src/hid/gerber/gerber.c Sat Jul 5 15:38:15 2008 *************** *** 472,478 **** pending_drills = 0; } ! is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); current_mask = 0; #if 0 --- 472,478 ---- pending_drills = 0; } ! is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL || SL_TYPE (idx) == SL_SPDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); current_mask = 0; #if 0 *************** *** 509,515 **** maybe_close_f (); pagecount++; ! switch (idx) { case SL (PDRILL, 0): sext = ".cnc"; --- 509,515 ---- maybe_close_f (); pagecount++; ! switch (SL_REMOVE_NO (idx)) { case SL (PDRILL, 0): sext = ".cnc"; *************** *** 517,522 **** --- 517,525 ---- case SL (UDRILL, 0): sext = ".cnc"; break; + case SL (SPDRILL, 0): /* special plated drill (i.e. blind and buried vias) */ + sext = ".cnc"; + break; } strcpy (filesuff, layer_type_to_file_name (idx)); strcat (filesuff, sext); diff -C 3 -r pcb-20080202/src/hid/hidint.h pcb-20080202-stefan_BA-20080703/src/hid/hidint.h *** pcb-20080202/src/hid/hidint.h Sat Jul 5 15:38:09 2008 --- pcb-20080202-stefan_BA-20080703/src/hid/hidint.h Sat Jul 5 15:38:15 2008 *************** *** 7,12 **** --- 7,14 ---- #define SL_TYPE(x) ((x) < 0 ? (x) & 0x0f0 : 0) #define SL_SIDE(x) ((x) & 0x00f) #define SL_MYSIDE(x) ((((x) & SL_BOTTOM_SIDE)!=0) == (SWAP_IDENT != 0)) + #define SL_NO(x) ((x) >> 16 & 0xff) + #define SL_REMOVE_NO(x) ((x) | 0xff0000) /* Called by the init funcs, used to set up hid_list. */ extern void hid_register_hid (HID * hid); diff -C 3 -r pcb-20080202/src/hid/nelma/nelma.c pcb-20080202-stefan_BA-20080703/src/hid/nelma/nelma.c *** pcb-20080202/src/hid/nelma/nelma.c Sat Jul 5 15:38:09 2008 --- pcb-20080202-stefan_BA-20080703/src/hid/nelma/nelma.c Sat Jul 5 15:38:15 2008 *************** *** 709,715 **** if (strcmp(name, "invisible") == 0) { return 0; } ! is_drill = (SL_TYPE(idx) == SL_PDRILL || SL_TYPE(idx) == SL_UDRILL); is_mask = (SL_TYPE(idx) == SL_MASK); if (is_mask) { --- 709,715 ---- if (strcmp(name, "invisible") == 0) { return 0; } ! is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL || SL_TYPE (idx) == SL_SPDRILL); is_mask = (SL_TYPE(idx) == SL_MASK); if (is_mask) { diff -C 3 -r pcb-20080202/src/hid/png/png.c pcb-20080202-stefan_BA-20080703/src/hid/png/png.c *** pcb-20080202/src/hid/png/png.c Sat Jul 5 15:38:09 2008 --- pcb-20080202-stefan_BA-20080703/src/hid/png/png.c Sat Jul 5 15:38:15 2008 *************** *** 523,529 **** if (strcmp (name, "invisible") == 0) return 0; ! is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); if (SL_TYPE (idx) == SL_PASTE) --- 523,529 ---- if (strcmp (name, "invisible") == 0) return 0; ! is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL || SL_TYPE (idx) == SL_SPDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); if (SL_TYPE (idx) == SL_PASTE) diff -C 3 -r pcb-20080202/src/hid/ps/eps.c pcb-20080202-stefan_BA-20080703/src/hid/ps/eps.c *** pcb-20080202/src/hid/ps/eps.c Sat Jul 5 15:38:09 2008 --- pcb-20080202-stefan_BA-20080703/src/hid/ps/eps.c Sat Jul 5 15:38:15 2008 *************** *** 323,329 **** if (strcmp (name, "invisible") == 0) return 0; ! is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); is_paste = (SL_TYPE (idx) == SL_PASTE); --- 323,329 ---- if (strcmp (name, "invisible") == 0) return 0; ! is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL || SL_TYPE (idx) == SL_SPDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); is_paste = (SL_TYPE (idx) == SL_PASTE); diff -C 3 -r pcb-20080202/src/hid/ps/ps.c pcb-20080202-stefan_BA-20080703/src/hid/ps/ps.c *** pcb-20080202/src/hid/ps/ps.c Sat Jul 5 15:38:09 2008 --- pcb-20080202-stefan_BA-20080703/src/hid/ps/ps.c Sat Jul 5 15:38:15 2008 *************** *** 513,519 **** if (strcmp (name, "invisible") == 0) return 0; ! is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); is_assy = (SL_TYPE (idx) == SL_ASSY); is_copper = (SL_TYPE (idx) == 0); --- 513,519 ---- if (strcmp (name, "invisible") == 0) return 0; ! is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL || SL_TYPE (idx) == SL_SPDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); is_assy = (SL_TYPE (idx) == SL_ASSY); is_copper = (SL_TYPE (idx) == 0); diff -C 3 -r pcb-20080202/src/hid.h pcb-20080202-stefan_BA-20080703/src/hid.h *** pcb-20080202/src/hid.h Sat Jul 5 15:38:10 2008 --- pcb-20080202-stefan_BA-20080703/src/hid.h Sat Jul 5 15:38:15 2008 *************** *** 194,201 **** --- 194,203 ---- #define SL_INVISIBLE 0x0060 #define SL_FAB 0x0070 #define SL_ASSY 0x0080 + #define SL_SPDRILL 0x0090 /* special plated drill (i.e. blind or buried vias) */ /* Callers should use this. */ #define SL(type,side) (~0xfff | SL_##type | SL_##side##_SIDE) + #define SLNO(type,side,no) (~0xff0fff | SL_##type | SL_##side##_SIDE | ((no) & 0xff) << 16 ) /* File Watch flags */ /* Based upon those in dbus/dbus-connection.h */ diff -C 3 -r pcb-20080202/src/macro.h pcb-20080202-stefan_BA-20080703/src/macro.h *** pcb-20080202/src/macro.h Sat Jul 5 15:38:10 2008 --- pcb-20080202-stefan_BA-20080703/src/macro.h Sat Jul 5 15:38:15 2008 *************** *** 207,212 **** --- 207,219 ---- extern int mem_any_set (unsigned char *, int); #define TEST_ANY_THERMS(P) mem_any_set((P)->Flags.t, sizeof((P)->Flags.t)) + #define TEST_DISAB_LAY(L,P) ((P)->Flags.dl[(L)>>3] & (1 << ((L) & 7)) ? 1 : 0) + #define SET_DISAB_LAY(L,P) (P)->Flags.dl[(L)>>3] |= (1 << ((L) & 7)) + #define CLEAR_DISAB_LAY(L,P) (P)->Flags.dl[(L)>>3] &= ~(1 << ((L) & 7)) + #define ASSIGN_DISAB_LAY(L,V,P) (P)->Flags.dl[(L)>>3] = ((P)->Flags.dl[(L)>>3] & ~(1 << ((L) & 7))) | ((V) ? 1 << ((L) & 7) : 0) + + #define TEST_ANY_DISAB_LAY(P) mem_any_set((P)->Flags.dl, sizeof((P)->Flags.dl)) + /* --------------------------------------------------------------------------- * access macros for elements name structure */ diff -C 3 -r pcb-20080202/src/polygon.c pcb-20080202-stefan_BA-20080703/src/polygon.c *** pcb-20080202/src/polygon.c Sat Jul 5 15:38:10 2008 --- pcb-20080202-stefan_BA-20080703/src/polygon.c Sat Jul 5 15:38:15 2008 *************** *** 524,529 **** --- 524,531 ---- if (pin->Clearance == 0) return 0; i = GetLayerNumber (d, l); + if (TEST_DISAB_LAY (i, pin)) /* do not subtract via if disabled for layer */ + return 0; if (TEST_THERM (i, pin)) { np = ThermPoly ((PCBTypePtr) (d->pcb), pin, i); diff -C 3 -r pcb-20080202/src/strflags.c pcb-20080202-stefan_BA-20080703/src/strflags.c *** pcb-20080202/src/strflags.c Sat Jul 5 15:38:10 2008 --- pcb-20080202-stefan_BA-20080703/src/strflags.c Sat Jul 5 15:38:15 2008 *************** *** 413,418 **** --- 413,424 ---- if (layers[i]) ASSIGN_THERM (i, layers[i], &rv); } + else if (flen == 12 && memcmp (fp, "disablelayer", 12) == 0) + { + for (i = 0; i < MAX_LAYER && i < num_layers; i++) + if (layers[i]) + ASSIGN_DISAB_LAY (i, layers[i], &rv); + } else { for (i = 0; i < n_flagbits; i++) *************** *** 515,520 **** --- 521,534 ---- len += printed_int_length (i, GET_THERM (i, &fh)) + 1; } + if (TEST_ANY_DISAB_LAY (&fh)) + { + len += sizeof ("disablelayer()"); + for (i = 0; i < MAX_LAYER; i++) + if (TEST_DISAB_LAY (i, &fh)) + len += printed_int_length (i, 0) + 1; + } + bp = buf = alloc_buf (len + 2); *bp++ = '"'; *************** *** 545,550 **** --- 559,578 ---- bp += strlen (bp); } + if (TEST_ANY_DISAB_LAY (&fh)) + { + if (bp != buf + 1) + *bp++ = ','; + strcpy (bp, "disablelayer"); + bp += strlen ("disablelayer"); + grow_layer_list (0); + for (i = 0; i < MAX_LAYER; i++) + if (TEST_DISAB_LAY (i, &fh)) + set_layer_list (i, 1); + strcpy (bp, print_layer_list ()); + bp += strlen (bp); + } + *bp++ = '"'; *bp = 0; return buf;