Index: trunk/src/libgrbs/collision.c =================================================================== --- trunk/src/libgrbs/collision.c (revision 1315) +++ trunk/src/libgrbs/collision.c (revision 1316) @@ -25,3 +25,15 @@ return 0; } + +static void coll_report(grbs_t *grbs, grbs_2net_t *tn, grbs_2net_t *coll_tn) +{ +#warning TODO: callback: use ->coll_report +} + + +static void coll_report_arc(grbs_t *grbs, grbs_2net_t *tn, grbs_arc_t *coll_arc) +{ + coll_report(grbs, tn, grbs_arc_parent_2net(coll_arc)); +} + Index: trunk/src/libgrbs/grbs.c =================================================================== --- trunk/src/libgrbs/grbs.c (revision 1315) +++ trunk/src/libgrbs/grbs.c (revision 1316) @@ -145,8 +145,8 @@ #include "geo.c" #include "addr.c" +#include "collision.c" #include "route_common.c" -#include "collision.c" #include "route_next.c" #include "route_realize.c" #include "route_remove.c" Index: trunk/src/libgrbs/route_common.c =================================================================== --- trunk/src/libgrbs/route_common.c (revision 1315) +++ trunk/src/libgrbs/route_common.c (revision 1316) @@ -23,7 +23,7 @@ /* Return if ang is a valid entry/exit point between two existing arcs (addr being the arc below) */ -static int grbs_angle_visible_between_arcs(grbs_t *grbs, grbs_addr_t *addr, double ang) +static int grbs_angle_visible_between_arcs(grbs_t *grbs, grbs_2net_t *tn, grbs_addr_t *addr, double ang) { grbs_arc_t *under = addr->obj.arc; grbs_arc_t *above = under->link_point.next; @@ -32,24 +32,31 @@ return 1; /* has to be within the arc under, else it will cross the under-arc or its line */ - if (!grbs_angle_in_arc(under->sa, under->da, ang, 1)) + if (!grbs_angle_in_arc(under->sa, under->da, ang, 1)) { + coll_report_arc(grbs, tn, under); return 0; + } /* has to be outside the arc above, else it will cross the above-arc or its line */ - if ((above != NULL) && (grbs_angle_in_arc(above->sa, above->da, ang, 0))) + if ((above != NULL) && (grbs_angle_in_arc(above->sa, above->da, ang, 0))) { + coll_report_arc(grbs, tn, above); return 0; + } return 1; } /* Check if a given angle range (for an arc) crosses any incident line of that pt */ -static int arc_crosses_any_incident(grbs_point_t *pt, double sa, double da) +static int arc_crosses_any_incident(grbs_t *grbs, grbs_2net_t *tn, grbs_point_t *pt, double sa, double da) { grbs_arc_t *i; - for(i = gdl_first(&pt->incs); i != NULL; i = gdl_next(&pt->incs, i)) - if (grbs_angle_in_arc(sa, da, i->sa, 0)) + for(i = gdl_first(&pt->incs); i != NULL; i = gdl_next(&pt->incs, i)) { + if (grbs_angle_in_arc(sa, da, i->sa, 0)) { + coll_report_arc(grbs, tn, i); return 1; + } + } return 0; } @@ -99,7 +106,7 @@ nsa = from->obj.arc->new_sa; nda = grbs_arc_get_delta(nsa, end_a, adir); - if (arc_crosses_any_incident(from->obj.arc->parent_pt, nsa, nda)) { + if (arc_crosses_any_incident(grbs, tn, from->obj.arc->parent_pt, nsa, nda)) { tprintf("tune4exit: incident cross\n"); return -1; } @@ -123,8 +130,10 @@ /* 'from' can extend anything only if it's a new segment - we never merge existing segments as that would always make crossings */ if (!is_new_seg) { - if (collides_next) + if (collides_next) { + coll_report_arc(grbs, tn, best_arc); goto fail; /* new arc within an existing segment would cross a different segment */ + } goto fin; } @@ -138,8 +147,10 @@ is if it becomes the first arc. By now we know it starts before the lowest orbit, because that's how it got a new segment originally. Check if end is beyond the lowest orbit of the target segment (best_arc) */ - if (grbs_angle_in_arc(best_arc->sa, best_arc->da, nsa+nda, 0)) + if (grbs_angle_in_arc(best_arc->sa, best_arc->da, nsa+nda, 0)) { + coll_report_arc(grbs, tn, best_arc); goto fail; /* existing arc would cross our new arc */ + } /* remove 'from' from its new segment and add it as lowest orbit under best_arc */ gdl_remove(&from_pt->arcs[from_conc][from->obj.arc->segi], from->obj.arc, link_point); Index: trunk/src/libgrbs/route_next.c =================================================================== --- trunk/src/libgrbs/route_next.c (revision 1315) +++ trunk/src/libgrbs/route_next.c (revision 1316) @@ -19,7 +19,7 @@ #define failprintf grbs_nullprintf #endif -static int grbs_inc_line_is_valid_(grbs_t *grbs, grbs_point_t *pt, double ang, double copper, double clearance, int is_concave) +static int grbs_inc_line_is_valid_(grbs_t *grbs, grbs_point_t *pt, double ang, double copper, double clearance, int is_concave, grbs_arc_t **coll) { grbs_arc_t *a; int side = 0; @@ -27,25 +27,29 @@ for(a = gdl_first(&pt->arcs[is_concave][side]); a != NULL; a = gdl_next(&pt->arcs[is_concave][side], a)) { double sa = a->sa, da = a->da; if (!a->in_use) continue; -#warning TODO: extend sa and da with copper and clearance - if (grbs_angle_in_arc(sa, da, ang, 0)) +#warning TODO: extend sa and da with copper and clearance; NOPE: concave postproc solved this + if (grbs_angle_in_arc(sa, da, ang, 0)) { + *coll = a; return 0; + } } return 1; } /* Return whether an incident line is valid (not crossing any arc around pt) */ -static int grbs_inc_line_is_valid(grbs_t *grbs, grbs_point_t *pt, double ang, double copper, double clearance) +static int grbs_inc_line_is_valid(grbs_t *grbs, grbs_point_t *pt, double ang, double copper, double clearance, grbs_arc_t **coll) { /* check for both convex and concave segments */ - return grbs_inc_line_is_valid_(grbs, pt, ang, copper, clearance, 0) && grbs_inc_line_is_valid_(grbs, pt, ang, copper, clearance, 1); + return grbs_inc_line_is_valid_(grbs, pt, ang, copper, clearance, 0, coll) && grbs_inc_line_is_valid_(grbs, pt, ang, copper, clearance, 1, coll); } -static int grbs_inc_line2arc_is_valid(grbs_t *grbs, grbs_point_t *pt, grbs_addr_t *addr, double arc_ang, double copper, double clearance) +static int grbs_inc_line2arc_is_valid(grbs_t *grbs, grbs_2net_t *tn, grbs_point_t *pt, grbs_addr_t *addr, double arc_ang, double copper, double clearance) { - grbs_arc_t *arc = addr->obj.arc; + grbs_arc_t *arc = addr->obj.arc, *coll; double r, ax, ay, vx, vy, ang; + int valid; + assert(!addr_is_incident(addr)); r = arc->new_r; ax = arc->parent_pt->x + cos(arc_ang) * r; @@ -53,7 +57,12 @@ vx = ax - pt->x; vy = ay - pt->y; ang = atan2(vy, vx); - return grbs_inc_line_is_valid(grbs, pt, ang, copper, clearance); + + valid = grbs_inc_line_is_valid(grbs, pt, ang, copper, clearance, &coll); + if (!valid) + coll_report_arc(grbs, tn, coll); + + return valid; } static grbs_addr_t *grbs_implement_incident(grbs_t *grbs, grbs_2net_t *tn, grbs_addr_t *from, double from_r, double from_a, grbs_point_t *to_pt, int segi, int new_at_from, grbs_addr_type_t curving, int concave_dir) @@ -149,7 +158,7 @@ /* Checks if concave-above-convex does not cross a convex arc's exit lines below. Returns 0 if the concave arc 'from' is valid or non-zero on crossing */ -static int concave_above_convex_validate(grbs_t *grbs, grbs_addr_t *from, double end_ang) +static int concave_above_convex_validate(grbs_t *grbs, grbs_2net_t *tn, grbs_addr_t *from, double end_ang) { int cvx_segi; @@ -161,8 +170,10 @@ start_in = grbs_angle_in_arc(cvx_sentinel->sa, cvx_sentinel->da, from->obj.arc->new_sa, 0); end_in = grbs_angle_in_arc(cvx_sentinel->sa, cvx_sentinel->da, end_ang, 0); - if (start_in != end_in) + if (start_in != end_in) { + coll_report_arc(grbs, tn, cvx_sentinel->link_point.next); return 1; + } } return 0; } @@ -199,7 +210,7 @@ double ox, oy; cnc_get_end(from, 1, &ox, &oy); from_ang = atan2(to_pt->y - oy, to_pt->x - ox); /* concave-target-angle (this will set ->new_da exit angle to face to to_pt) */ - if (concave_above_convex_validate(grbs, from, from_ang) != 0) { + if (concave_above_convex_validate(grbs, tn, from, from_ang) != 0) { failprintf("concave-above-convex: invalid exit angle (concave arc crosses convex exit)\n"); return NULL; } @@ -210,7 +221,7 @@ } - if (!grbs_inc_line2arc_is_valid(grbs, to_pt, from, from_ang, tn->copper, tn->clearance)) { + if (!grbs_inc_line2arc_is_valid(grbs, tn, to_pt, from, from_ang, tn->copper, tn->clearance)) { failprintf("inc_line2arc_is_valid\n"); return NULL; } @@ -241,12 +252,12 @@ assert(grbs_adir_is_arc(to_adir)); - if (!grbs_angle_visible_between_arcs(grbs, to, a[to_adir])) { + if (!grbs_angle_visible_between_arcs(grbs, tn, to, a[to_adir])) { failprintf("angle visible between arcs\n"); return NULL; } - if (!grbs_inc_line2arc_is_valid(grbs, from_pt, to, a[to_adir], tn->copper, tn->clearance)) { + if (!grbs_inc_line2arc_is_valid(grbs, tn, from_pt, to, a[to_adir], tn->copper, tn->clearance)) { failprintf("inc_line2arc_is_valid\n"); return NULL; } @@ -274,12 +285,12 @@ to_ang += ((to_adir == GRBS_ADIR_CONCAVE_CCW) ? -1 : +1) * (tn->copper + tn->clearance) / tor_r ; - if (!grbs_angle_visible_between_arcs(grbs, to, to_ang)) { + if (!grbs_angle_visible_between_arcs(grbs, tn, to, to_ang)) { failprintf("angle visible between arcs\n"); return NULL; } - if (!grbs_inc_line2arc_is_valid(grbs, from_pt, to, to_ang, tn->copper, tn->clearance)) { + if (!grbs_inc_line2arc_is_valid(grbs, tn, from_pt, to, to_ang, tn->copper, tn->clearance)) { failprintf("inc_line2arc_is_valid\n"); return NULL; } @@ -290,16 +301,19 @@ static grbs_addr_t *path_find_inc2inc(grbs_t *grbs, grbs_2net_t *tn, grbs_addr_t *from, grbs_point_t *to_pt) { + grbs_arc_t *coll; grbs_point_t *from_pt = addr_point(from); double vx = to_pt->x - from_pt->x, vy = to_pt->y - from_pt->y; double ang = atan2(vy, vx); - if (!grbs_inc_line_is_valid(grbs, from_pt, ang, tn->copper, tn->clearance)) { + if (!grbs_inc_line_is_valid(grbs, from_pt, ang, tn->copper, tn->clearance, &coll)) { failprintf("inc_line_is_valid: from\n"); + coll_report_arc(grbs, tn, coll); return NULL; } - if (!grbs_inc_line_is_valid(grbs, to_pt, ang - M_PI, tn->copper, tn->clearance)) { + if (!grbs_inc_line_is_valid(grbs, to_pt, ang - M_PI, tn->copper, tn->clearance, &coll)) { failprintf("inc_line_is_valid: to\n"); + coll_report_arc(grbs, tn, coll); return NULL; } @@ -579,11 +593,11 @@ /* printf("arc2arc crossbelt: %d r: %f -> %f ang: %f %f\n", crossbelt, fromr_r, tor_r, a[0], a[2]); */ - if (!grbs_angle_visible_between_arcs(grbs, from, a[from_ang_side])) { + if (!grbs_angle_visible_between_arcs(grbs, tn, from, a[from_ang_side])) { failprintf("between-arcs: from\n"); return NULL; } - if (!grbs_angle_visible_between_arcs(grbs, to, a[to_adir_idx+2])) { + if (!grbs_angle_visible_between_arcs(grbs, tn, to, a[to_adir_idx+2])) { failprintf("between-arcs: to\n"); return NULL; }