Index: trunk/src/find.c =================================================================== --- trunk/src/find.c (revision 37385) +++ trunk/src/find.c (revision 37386) @@ -386,7 +386,7 @@ } \ } while(0) -#define PCB_FIND_CHECK_RAT(ctx, curr, obj, ctype, retstmt) \ +#define PCB_FIND_CHECK_RAT_GEO(ctx, curr, obj, ctype, retstmt) \ do { \ pcb_any_obj_t *__obj__ = (pcb_any_obj_t *)obj; \ if (!pcb_find_mark_get(ctx, __obj__, (curr))) { \ @@ -398,6 +398,35 @@ } \ } while(0) +#define PCB_FIND_CHECK_RAT_IDP(ctx, curr, rat, ctype, retstmt) \ + do { \ + int n; \ + pcb_any_obj_t *__obj__ = (pcb_any_obj_t *)rat; \ + for(n = 0; n < 2; n++) { \ + if (pcb_idpath_obj_match(ctx->pcb, rat->anchor[n], curr)) { \ + if (pcb_find_addobj(ctx, __obj__, curr, ctype, ctx->consider_rats) != 0) { retstmt; } \ + if ((__obj__->term != NULL) && (!ctx->ignore_intconn) && (__obj__->intconn > 0)) \ + find_int_conn(ctx, __obj__); \ + } \ + } \ + } while(0) + + +/* If anchors are available, check object idpath against the anchor instead + of fiding intersections; this is safer because other objects on the same + point/layer can be present; corner case: two nointconn lines intersect + at their endpoints and a rat is drawn to one of them - if we go by _GEO(), + the rat's endpoint still connects them! */ +#define PCB_FIND_CHECK_RAT(ctx, curr, obj, ctype, retstmt) \ + do { \ + pcb_rat_t *rat = (pcb_rat_t *)obj; \ + if ((rat->anchor[0] != NULL) && (rat->anchor[1] != NULL)) \ + PCB_FIND_CHECK_RAT_IDP(ctx, curr, rat, ctype, retstmt); \ + else \ + PCB_FIND_CHECK_RAT_GEO(ctx, curr, obj, ctype, retstmt); \ + } while(0) + + void pcb_find_on_layer(pcb_find_t *ctx, pcb_layer_t *l, pcb_any_obj_t *curr, rnd_rtree_box_t *sb, pcb_found_conn_type_t ctype) { rnd_rtree_it_t it; Index: trunk/src/find_geo.c =================================================================== --- trunk/src/find_geo.c (revision 37385) +++ trunk/src/find_geo.c (revision 37386) @@ -268,6 +268,19 @@ return rnd_false; } +/* If anchors are available: return true if obj is one of the two anchors, else + return false. If no anchors, don't do anything */ +#define PCB_ISC_RAT_BY_IDPATH(ctx, rat, obj) \ + do { \ + if ((rat->anchor[0] != NULL) && (rat->anchor[1] != NULL)) { \ + int n; \ + for(n = 0; n < 2; n++) \ + if (pcb_idpath_obj_match(ctx->pcb, rat->anchor[n], (obj))) \ + return rnd_true; \ + return rnd_false; \ + } \ + } while(0) + /* --------------------------------------------------------------------------- * Tests if point is same as line end point or center point */ @@ -293,6 +306,8 @@ { rnd_layergrp_id_t gid = pcb_layer_get_group_(line->parent.layer); + PCB_ISC_RAT_BY_IDPATH(ctx, rat, (pcb_any_obj_t *)line); + if ((rat->group1 == gid) && pcb_isc_ratp_line(ctx, &rat->Point1, line)) return rnd_true; if ((rat->group2 == gid) && pcb_isc_ratp_line(ctx, &rat->Point2, line)) @@ -330,6 +345,8 @@ { rnd_layergrp_id_t gid = pcb_layer_get_group_(arc->parent.layer); + PCB_ISC_RAT_BY_IDPATH(ctx, rat, (pcb_any_obj_t *)arc); + if ((rat->group1 == gid) && pcb_isc_ratp_arc(ctx, &rat->Point1, arc)) return rnd_true; if ((rat->group2 == gid) && pcb_isc_ratp_arc(ctx, &rat->Point2, arc)) @@ -398,6 +415,8 @@ rnd_layergrp_id_t gid = pcb_layer_get_group_(poly->parent.layer); int donut = PCB_FLAG_TEST(PCB_FLAG_VIA, rat); + PCB_ISC_RAT_BY_IDPATH(ctx, rat, (pcb_any_obj_t *)poly); + if ((rat->group1 == gid) && pcb_isc_ratp_poly(ctx, &rat->Point1, poly, donut)) return rnd_true; if ((rat->group2 == gid) && pcb_isc_ratp_poly(ctx, &rat->Point2, poly, donut)) @@ -409,6 +428,10 @@ /* Tests any end of a rat line is on the other rat */ static rnd_bool pcb_isc_rat_rat(const pcb_find_t *ctx, pcb_rat_t *r1, pcb_rat_t *r2) { + +/* Can't do this by idpath: a rat will never have another rat for anchor! + PCB_ISC_RAT_BY_IDPATH(ctx, r1, (pcb_any_obj_t *)r2); */ + if ((r1->group1 == r2->group1) && (r1->Point1.X == r2->Point1.X) && (r1->Point1.Y == r2->Point1.Y)) return rnd_true; if ((r1->group2 == r2->group2) && (r1->Point2.X == r2->Point2.X) && (r1->Point2.Y == r2->Point2.Y)) @@ -1420,6 +1443,8 @@ { pcb_board_t *pcb = PCB; + PCB_ISC_RAT_BY_IDPATH(ctx, rat, (pcb_any_obj_t *)ps); + if ((rat->Point1.X == ps->x) && (rat->Point1.Y == ps->y)) { pcb_layer_t *layer = pcb_get_layer(pcb->Data, pcb->LayerGroups.grp[rat->group1].lid[0]); if ((layer != NULL) && (pcb_pstk_shape_at(pcb, ps, layer) != NULL))