Index: trunk/src/find.c =================================================================== --- trunk/src/find.c (revision 12305) +++ trunk/src/find.c (revision 12306) @@ -158,6 +158,7 @@ * some local prototypes */ static pcb_bool LookupLOConnectionsToPVList(pcb_bool); +static pcb_bool LookupLOConnectionsToPSList(pcb_bool); static pcb_bool LookupLOConnectionsToLOList(pcb_bool); static pcb_bool LookupPVConnectionsToLOList(pcb_bool); static pcb_bool LookupPVConnectionsToPVList(void); Index: trunk/src/find_geo.c =================================================================== --- trunk/src/find_geo.c (revision 12305) +++ trunk/src/find_geo.c (revision 12306) @@ -42,6 +42,7 @@ #include "macro.h" #include "obj_arc_ui.h" +#include "obj_padstack_inlines.h" #define EXPAND_BOUNDS(p) if (Bloat > 0) {\ (p)->BoundingBox.X1 -= Bloat; \ @@ -750,7 +751,54 @@ } - /* the original round pin version */ return pcb_is_point_in_pad(PV->X, PV->Y, MAX(PIN_SIZE(PV) / 2.0 + Bloat, 0.0), (pcb_pad_t *) Line); } + + +static inline PCB_FUNC_UNUSED pcb_bool_t pcb_padstack_intersect_line(pcb_padstack_t *ps, pcb_line_t *line) +{ + pcb_padstack_shape_t *shape = pcb_padstack_shape_at(PCB, ps, line->parent.layer); + if (shape == NULL) return pcb_false; + switch(shape->shape) { + case PCB_PSSH_POLY: + case PCB_PSSH_LINE: + { + pcb_line_t tmp; + tmp.Point1.X = shape->data.line.x1; + tmp.Point1.Y = shape->data.line.y1; + tmp.Point2.X = shape->data.line.x2; + tmp.Point2.Y = shape->data.line.y2; + tmp.Thickness = shape->data.line.thickness; + tmp.Flags = shape->data.line.square ? pcb_flag_make(PCB_FLAG_SQUARE) : pcb_no_flags(); + return pcb_intersect_line_line(line, &tmp); + } + case PCB_PSSH_CIRC: + break; + } + return pcb_false; +} + + +static inline PCB_FUNC_UNUSED pcb_bool_t pcb_padstack_intersect_arc(pcb_padstack_t *ps, pcb_arc_t *arc) +{ + pcb_padstack_shape_t *shape = pcb_padstack_shape_at(PCB, ps, arc->parent.layer); + if (shape == NULL) return pcb_false; + switch(shape->shape) { + case PCB_PSSH_POLY: + case PCB_PSSH_LINE: + case PCB_PSSH_CIRC: + break; + } + return pcb_false; +} + +static inline PCB_FUNC_UNUSED pcb_bool_t pcb_padstack_intersect_poly(pcb_padstack_t *ps, pcb_poly_t *poly) +{ + return pcb_false; +} + +static inline PCB_FUNC_UNUSED pcb_bool_t pcb_padstack_intersect_rat(pcb_padstack_t *ps, pcb_rat_t *rat) +{ + return ((rat->Point1.X == ps->x) && (rat->Point1.Y == ps->y)) || ((rat->Point2.X == ps->x) && (rat->Point2.Y == ps->y)); +} Index: trunk/src/find_lookup.c =================================================================== --- trunk/src/find_lookup.c (revision 12305) +++ trunk/src/find_lookup.c (revision 12306) @@ -422,6 +422,60 @@ return PCB_R_DIR_NOT_FOUND; } +struct ps_info { + pcb_layer_id_t layer; + pcb_padstack_t ps; + jmp_buf env; +}; + +static pcb_r_dir_t LOCtoPSline_callback(const pcb_box_t * b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *) b; + struct ps_info *i = (struct ps_info *) cl; + + if (!PCB_FLAG_TEST(TheFlag, line) && pcb_padstack_intersect_line(&i->ps, line)) { + if (ADD_LINE_TO_LIST(i->layer, line, PCB_TYPE_PADSTACK, &i->ps, PCB_FCT_COPPER)) + longjmp(i->env, 1); + } + return PCB_R_DIR_NOT_FOUND; +} + +static pcb_r_dir_t LOCtoPSarc_callback(const pcb_box_t * b, void *cl) +{ + pcb_arc_t *arc = (pcb_arc_t *) b; + struct ps_info *i = (struct ps_info *) cl; + + if (!PCB_FLAG_TEST(TheFlag, arc) && pcb_padstack_intersect_arc(&i->ps, arc)) { + if (ADD_ARC_TO_LIST(i->layer, arc, PCB_TYPE_PADSTACK, &i->ps, PCB_FCT_COPPER)) + longjmp(i->env, 1); + } + return PCB_R_DIR_NOT_FOUND; +} + +static pcb_r_dir_t LOCtoPSrat_callback(const pcb_box_t * b, void *cl) +{ + pcb_rat_t *rat = (pcb_rat_t *) b; + struct ps_info *i = (struct ps_info *) cl; + + if (!PCB_FLAG_TEST(TheFlag, rat) && pcb_padstack_intersect_rat(&i->ps, rat) && ADD_RAT_TO_LIST(rat, PCB_TYPE_PIN, &i->ps, PCB_FCT_RAT)) + longjmp(i->env, 1); + return PCB_R_DIR_NOT_FOUND; +} + +static pcb_r_dir_t LOCtoPSpoly_callback(const pcb_box_t * b, void *cl) +{ + pcb_poly_t *polygon = (pcb_poly_t *) b; + struct ps_info *i = (struct ps_info *) cl; + + if (!PCB_FLAG_TEST(TheFlag, polygon) && pcb_padstack_intersect_poly(&i->ps, polygon)) { + if (ADD_POLYGON_TO_LIST(i->layer, polygon, PCB_TYPE_PADSTACK, &i->ps, PCB_FCT_COPPER)) + longjmp(i->env, 1); + } + + return PCB_R_DIR_NOT_FOUND; +} + + /* --------------------------------------------------------------------------- * checks if a PV is connected to LOs, if it is, the LO is added to * the appropriate list and the 'used' flag is set @@ -485,6 +539,62 @@ } /* --------------------------------------------------------------------------- + * checks if a padstack is connected to LOs, if it is, the LO is added to + * the appropriate list and the 'used' flag is set + */ +static pcb_bool LookupLOConnectionsToPSList(pcb_bool AndRats) +{ + pcb_cardinal_t layer; + struct ps_info info; + pcb_padstack_t *orig_ps; + + /* loop over all PVs currently on list */ + while (PadstackList.Location < PadstackList.Number) { + /* get pointer to data */ + orig_ps = (PADSTACKLIST_ENTRY(PadstackList.Location)); + info.ps = *orig_ps; + EXPAND_BOUNDS(&info.ps); + + /* subc intconn jumps */ + if ((orig_ps->term != NULL) && (orig_ps->intconn > 0)) + LOC_int_conn_subc(pcb_gobj_parent_subc(orig_ps->parent_type, &orig_ps->parent), orig_ps->intconn, PCB_TYPE_PADSTACK, orig_ps); + + /* now all lines, arcs and polygons of the several layers */ + for(layer = 0; layer < pcb_max_layer; layer++) { + if (!(pcb_layer_flags(PCB, layer) & PCB_LYT_COPPER)) + continue; + if (LAYER_PTR(layer)->meta.real.no_drc) + continue; + info.layer = layer; + /* add touching lines */ + if (setjmp(info.env) == 0) + pcb_r_search(LAYER_PTR(layer)->line_tree, (pcb_box_t *) & info.ps, NULL, LOCtoPSline_callback, &info, NULL); + else + return pcb_true; + /* add touching arcs */ + if (setjmp(info.env) == 0) + pcb_r_search(LAYER_PTR(layer)->arc_tree, (pcb_box_t *) & info.ps, NULL, LOCtoPSarc_callback, &info, NULL); + else + return pcb_true; + /* check all polygons */ + if (setjmp(info.env) == 0) + pcb_r_search(LAYER_PTR(layer)->polygon_tree, (pcb_box_t *) & info.ps, NULL, LOCtoPSpoly_callback, &info, NULL); + else + return pcb_true; + } + /* Check for rat-lines that may intersect the PV */ + if (AndRats) { + if (setjmp(info.env) == 0) + pcb_r_search(PCB->Data->rat_tree, (pcb_box_t *) & info.ps, NULL, LOCtoPSrat_callback, &info, NULL); + else + return pcb_true; + } + PadstackList.Location++; + } + return pcb_false; +} + +/* --------------------------------------------------------------------------- * find all connections between LO at the current list position and new LOs */ static pcb_bool LookupLOConnectionsToLOList(pcb_bool AndRats) Index: trunk/src/find_misc.c =================================================================== --- trunk/src/find_misc.c (revision 12305) +++ trunk/src/find_misc.c (revision 12306) @@ -70,6 +70,7 @@ newone = LookupPVConnectionsToPVList() || LookupLOConnectionsToPVList(AndRats) || + LookupLOConnectionsToPSList(AndRats) || LookupLOConnectionsToLOList(AndRats) || LookupPVConnectionsToLOList(AndRats); if (AndDraw) Index: trunk/src/obj_padstack_inlines.h =================================================================== --- trunk/src/obj_padstack_inlines.h (revision 12305) +++ trunk/src/obj_padstack_inlines.h (revision 12306) @@ -20,8 +20,13 @@ * */ +#ifndef PCB_OBJ_PADSTACK_INLINES_H +#define PCB_OBJ_PADSTACK_INLINES_H + +#include "board.h" #include "obj_padstack.h" #include "vtpadstack.h" +#include "layer.h" typedef enum { PCB_BB_NONE, /* no drill */ @@ -124,3 +129,25 @@ return 0; } + +static inline PCB_FUNC_UNUSED pcb_padstack_shape_t *pcb_padstack_shape_at(pcb_board_t *pcb, pcb_padstack_t *ps, pcb_layer_t *layer) +{ + unsigned int lyt = pcb_layer_flags_(layer); + pcb_layer_combining_t comb = 0; + + if ((lyt & PCB_LYT_COPPER) && (lyt & PCB_LYT_INTERN)) { + /* apply internal only if that layer has drill */ + if (!pcb_padstack_bb_drills(pcb, ps, pcb_layer_get_group_(layer), NULL)) + return NULL; + } + + /* combining is always 0 for copper */ + if (lyt & PCB_LYT_COPPER) + comb = 0; + else + comb = layer->comb; + + return pcb_padstack_shape(ps, lyt, comb); +} + +#endif