Compare commits

...

2 Commits

@ -464,53 +464,52 @@ class Pather(Builder):
xd, yd = port_dst.offset xd, yd = port_dst.offset
angle = (port_dst.rotation - port_src.rotation) % (2 * pi) angle = (port_dst.rotation - port_src.rotation) % (2 * pi)
kwargs['tool_port_names'] = tool_port_names
src_ne = port_src.rotation % (2 * pi) > (3 * pi /4) # path from src will go north or east src_ne = port_src.rotation % (2 * pi) > (3 * pi /4) # path from src will go north or east
dst_args = {'out_ptype': out_ptype}
if plug_destination:
dst_args['plug_into'] = portspec_dst
def get_jog(ccw: SupportsBool, length: float) -> float: def get_jog(ccw: SupportsBool, length: float) -> float:
tool = self.tools.get(portspec_src, self.tools[None]) tool = self.tools.get(portspec_src, self.tools[None])
in_ptype = 'unk' # Could use port_src.ptype, but we're assuming this is after one bend already... in_ptype = 'unk' # Could use port_src.ptype, but we're assuming this is after one bend already...
tree2 = tool.path(ccw, y_len, in_ptype=in_ptype, port_names=('A', 'B'), out_ptype=out_ptype, **kwargs) tree2 = tool.path(ccw, length, in_ptype=in_ptype, port_names=('A', 'B'), out_ptype=out_ptype, **kwargs)
top2 = tree2.top_pattern() top2 = tree2.top_pattern()
jog = rotation_matrix_2d(top2['A'].rotation) @ (top2['B'].offset - top2['A'].offset) jog = rotation_matrix_2d(top2['A'].rotation) @ (top2['B'].offset - top2['A'].offset)
return jog[1] return jog[1]
all_dst_args = {**kwargs, **dst_args} dst_extra_args = {'out_ptype': out_ptype}
if plug_destination:
dst_extra_args['plug_into'] = portspec_dst
src_args = {**kwargs, 'tool_port_names': tool_port_names}
dst_args = {**src_args, **dst_extra_args}
if src_is_horizontal and not dst_is_horizontal: if src_is_horizontal and not dst_is_horizontal:
# single bend should suffice # single bend should suffice
self.path_to(portspec_src, angle > pi, x=xd, **kwargs) self.path_to(portspec_src, angle > pi, x=xd, **src_args)
self.path_to(portspec_src, None, y=yd, **all_dst_args) self.path_to(portspec_src, None, y=yd, **dst_args)
elif dst_is_horizontal and not src_is_horizontal: elif dst_is_horizontal and not src_is_horizontal:
# single bend should suffice # single bend should suffice
self.path_to(portspec_src, angle > pi, y=yd, **kwargs) self.path_to(portspec_src, angle > pi, y=yd, **src_args)
self.path_to(portspec_src, None, x=xd, **all_dst_args) self.path_to(portspec_src, None, x=xd, **dst_args)
elif numpy.isclose(angle, pi): elif numpy.isclose(angle, pi):
if src_is_horizontal and ys == yd: if src_is_horizontal and ys == yd:
# straight connector # straight connector
self.path_to(portspec_src, None, x=xd, **all_dst_args) self.path_to(portspec_src, None, x=xd, **dst_args)
elif not src_is_horizontal and xs == xd: elif not src_is_horizontal and xs == xd:
# straight connector # straight connector
self.path_to(portspec_src, None, y=yd, **all_dst_args) self.path_to(portspec_src, None, y=yd, **dst_args)
elif src_is_horizontal: elif src_is_horizontal:
# figure out how much x our y-segment (2nd) takes up, then path based on that # figure out how much x our y-segment (2nd) takes up, then path based on that
y_len = numpy.abs(yd - ys) y_len = numpy.abs(yd - ys)
ccw2 = src_ne != (yd > ys) ccw2 = src_ne != (yd > ys)
jog = get_jog(ccw2, y_len) * numpy.sign(xd - xs) jog = get_jog(ccw2, y_len) * numpy.sign(xd - xs)
self.path_to(portspec_src, not ccw2, x=xd - jog, **kwargs) self.path_to(portspec_src, not ccw2, x=xd - jog, **src_args)
self.path_to(portspec_src, ccw2, y=yd, **all_dst_args) self.path_to(portspec_src, ccw2, y=yd, **dst_args)
else: else:
# figure out how much y our x-segment (2nd) takes up, then path based on that # figure out how much y our x-segment (2nd) takes up, then path based on that
x_len = numpy.abs(xd - xs) x_len = numpy.abs(xd - xs)
ccw2 = src_ne != (xd < xs) ccw2 = src_ne != (xd < xs)
jog = get_jog(ccw2, x_len) * numpy.sign(yd - ys) jog = get_jog(ccw2, x_len) * numpy.sign(yd - ys)
self.path_to(portspec_src, not ccw2, y=yd - jog, **kwargs) self.path_to(portspec_src, not ccw2, y=yd - jog, **src_args)
self.path_to(portspec_src, ccw2, x=xd, **all_dst_args) self.path_to(portspec_src, ccw2, x=xd, **dst_args)
elif numpy.isclose(angle, 0): elif numpy.isclose(angle, 0):
raise BuildError(f'Don\'t know how to route a U-bend at this time!') raise BuildError(f'Don\'t know how to route a U-bend at this time!')
else: else:

@ -62,7 +62,8 @@ def maxrects_bssf(
''' Place the rect ''' ''' Place the rect '''
# Best short-side fit (bssf) to pick a region # Best short-side fit (bssf) to pick a region
bssf_scores = ((regions[:, 2:] - regions[:, :2]) - rect_size).min(axis=1).astype(float) region_sizes = regions[:, 2:] - regions[:, :2]
bssf_scores = (region_sizes - rect_size).min(axis=1).astype(float)
bssf_scores[bssf_scores < 0] = numpy.inf # doesn't fit! bssf_scores[bssf_scores < 0] = numpy.inf # doesn't fit!
rr = bssf_scores.argmin() rr = bssf_scores.argmin()
if numpy.isinf(bssf_scores[rr]): if numpy.isinf(bssf_scores[rr]):
@ -152,7 +153,8 @@ def guillotine_bssf_sas(
for rect_ind, rect_size in enumerate(rect_sizes): for rect_ind, rect_size in enumerate(rect_sizes):
''' Place the rect ''' ''' Place the rect '''
# Best short-side fit (bssf) to pick a region # Best short-side fit (bssf) to pick a region
bssf_scores = ((regions[:, 2:] - regions[:, :2]) - rect_size).min(axis=1).astype(float) region_sizes = regions[:, 2:] - regions[:, :2]
bssf_scores = (region_sizes - rect_size).min(axis=1).astype(float)
bssf_scores[bssf_scores < 0] = numpy.inf # doesn't fit! bssf_scores[bssf_scores < 0] = numpy.inf # doesn't fit!
rr = bssf_scores.argmin() rr = bssf_scores.argmin()
if numpy.isinf(bssf_scores[rr]): if numpy.isinf(bssf_scores[rr]):
@ -166,7 +168,7 @@ def guillotine_bssf_sas(
loc = regions[rr, :2] loc = regions[rr, :2]
rect_locs[rect_ind] = loc rect_locs[rect_ind] = loc
region_size = regions[rr, 2:] - loc region_size = region_sizes[rr]
split_horiz = region_size[0] < region_size[1] split_horiz = region_size[0] < region_size[1]
new_region0 = regions[rr].copy() new_region0 = regions[rr].copy()

Loading…
Cancel
Save