Index: trunk/src/obj_line.h =================================================================== --- trunk/src/obj_line.h (revision 24048) +++ trunk/src/obj_line.h (revision 24049) @@ -100,18 +100,24 @@ void pcb_line_enforce_drc(void); -/* Checks for intersectors against two lines and - * adjusts the end point until there is no intersection or - * it winds up back at the start. If way is pcb_false it checks - * an ortho start line with one 45 refraction to reach the endpoint, - * otherwise it checks a 45 start, with a ortho refraction to reach endpoint - * - * It returns the straight-line length of the best answer, and - * changes the position of 'end' to the best answer. - */ -double pcb_drc_lines(const pcb_point_t *start, pcb_point_t *end, pcb_bool way); +/* Calculate a pair of refractioned (ortho-45) lines between 'start' and 'end'. + If 'mid_out' is not NULL, load it with the coords of the middle point. + If way is false it checks an ortho start line with one 45 refraction to + reach the endpoint, otherwise it checks a 45 start, with a ortho refraction + to reach endpoint. + Checks for intersectors against two lines. + If optimize is false, return straight-line distance between start and end + on success or -1 if the pair-of-lines has hit a blocker object. + + If optimize is true, keep on looking for a mid-way solution, adjusting + the fields of 'end' needed to find the closest point to the original target + that still won't hit any object. Returns the straigh-line distance between + start and the new end. */ +double pcb_drc_lines(const pcb_point_t *start, pcb_point_t *end, pcb_point_t *mid_out, pcb_bool way, pcb_bool optimize); + + /* Rather than mode the line bounding box, we set it so the point bounding * boxes are updated too. */ Index: trunk/src/obj_line_drcenf.c =================================================================== --- trunk/src/obj_line_drcenf.c (revision 24048) +++ trunk/src/obj_line_drcenf.c (revision 24049) @@ -228,7 +228,7 @@ return PCB_R_DIR_FOUND_CONTINUE; } -double pcb_drc_lines(const pcb_point_t *start, pcb_point_t *end, pcb_bool way) +double pcb_drc_lines(const pcb_point_t *start, pcb_point_t *end, pcb_point_t *mid_out, pcb_bool way, pcb_bool optimize) { double f, s, f2, s2, len, best; pcb_coord_t dx, dy, temp, last, length; @@ -383,10 +383,21 @@ f -= s; s *= 0.5; length = MIN(f * temp, temp); + if (!optimize) { + if (blocker) + best = -1; + else + best = length; + break; + } } end->X = ans.X; end->Y = ans.Y; + if (mid_out != NULL) { + mid_out->X = line1.Point2.X; + mid_out->Y = line1.Point2.Y; + } return best; } @@ -472,9 +483,9 @@ if (conf_core.editor.line_refraction != 0) { /* first try starting straight */ - r1 = pcb_drc_lines(&start, &rs, pcb_false); + r1 = pcb_drc_lines(&start, &rs, NULL, pcb_false, pcb_true); /* then try starting at 45 */ - r2 = pcb_drc_lines(&start, &r45, pcb_true); + r2 = pcb_drc_lines(&start, &r45, NULL, pcb_true, pcb_true); } else { drc_line(&rs);