Compare commits
No commits in common. "e7f847d4c773a621e30818e4f806a5e19e754e86" and "d03fafcaf6718d9af4bb9d23667d92c961a17507" have entirely different histories.
e7f847d4c7
...
d03fafcaf6
10 changed files with 14 additions and 228 deletions
|
|
@ -415,17 +415,8 @@ class Pather(PortList):
|
||||||
self._apply_dead_fallback(portspec, length, jog, None, in_ptype, plug_into, out_rot=pi)
|
self._apply_dead_fallback(portspec, length, jog, None, in_ptype, plug_into, out_rot=pi)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
try:
|
self._traceL(portspec, ccw0, L1, **(kwargs | {'out_ptype': None}))
|
||||||
out_port0, data0 = tool.planL(ccw0, L1, in_ptype=in_ptype, **(kwargs | {'out_ptype': None}))
|
self._traceL(portspec, not ccw0, L2, **(kwargs | {'plug_into': plug_into}))
|
||||||
out_port1, data1 = tool.planL(not ccw0, L2, in_ptype=out_port0.ptype, **kwargs)
|
|
||||||
except (BuildError, NotImplementedError):
|
|
||||||
if not self._dead:
|
|
||||||
raise
|
|
||||||
self._apply_dead_fallback(portspec, length, jog, None, in_ptype, plug_into, out_rot=pi)
|
|
||||||
return self
|
|
||||||
|
|
||||||
self._apply_step('L', portspec, out_port0, data0, tool)
|
|
||||||
self._apply_step('L', portspec, out_port1, data1, tool, plug_into)
|
|
||||||
return self
|
return self
|
||||||
if out_port is not None:
|
if out_port is not None:
|
||||||
self._apply_step('S', portspec, out_port, data, tool, plug_into)
|
self._apply_step('S', portspec, out_port, data, tool, plug_into)
|
||||||
|
|
@ -445,16 +436,14 @@ class Pather(PortList):
|
||||||
try:
|
try:
|
||||||
R = self._get_tool_R(tool, ccw, in_ptype, **kwargs)
|
R = self._get_tool_R(tool, ccw, in_ptype, **kwargs)
|
||||||
L1, L2 = length + R, abs(jog) - R
|
L1, L2 = length + R, abs(jog) - R
|
||||||
out_port0, data0 = tool.planL(ccw, L1, in_ptype=in_ptype, **(kwargs | {'out_ptype': None}))
|
self._traceL(portspec, ccw, L1, **(kwargs | {'out_ptype': None}))
|
||||||
out_port1, data1 = tool.planL(ccw, L2, in_ptype=out_port0.ptype, **kwargs)
|
self._traceL(portspec, ccw, L2, **(kwargs | {'plug_into': plug_into}))
|
||||||
except (BuildError, NotImplementedError):
|
except (BuildError, NotImplementedError):
|
||||||
if not self._dead:
|
if not self._dead:
|
||||||
raise
|
raise
|
||||||
self._apply_dead_fallback(portspec, length, jog, None, in_ptype, plug_into, out_rot=0)
|
self._apply_dead_fallback(portspec, length, jog, None, in_ptype, plug_into, out_rot=0)
|
||||||
return self
|
return self
|
||||||
else:
|
else:
|
||||||
self._apply_step('L', portspec, out_port0, data0, tool)
|
|
||||||
self._apply_step('L', portspec, out_port1, data1, tool, plug_into)
|
|
||||||
return self
|
return self
|
||||||
if out_port is not None:
|
if out_port is not None:
|
||||||
self._apply_step('U', portspec, out_port, data, tool, plug_into)
|
self._apply_step('U', portspec, out_port, data, tool, plug_into)
|
||||||
|
|
|
||||||
|
|
@ -1031,7 +1031,7 @@ class AutoTool(Tool, metaclass=ABCMeta):
|
||||||
jog_remaining = jog - itrans_dxy[1] - otrans_dxy[1]
|
jog_remaining = jog - itrans_dxy[1] - otrans_dxy[1]
|
||||||
if sbend.jog_range[0] <= jog_remaining < sbend.jog_range[1]:
|
if sbend.jog_range[0] <= jog_remaining < sbend.jog_range[1]:
|
||||||
sbend_dxy = self._sbend2dxy(sbend, jog_remaining)
|
sbend_dxy = self._sbend2dxy(sbend, jog_remaining)
|
||||||
success = numpy.isclose(length, sbend_dxy[0] + itrans_dxy[0] + otrans_dxy[0])
|
success = numpy.isclose(length, sbend_dxy[0] + itrans_dxy[1] + otrans_dxy[1])
|
||||||
if success:
|
if success:
|
||||||
b_transition = None
|
b_transition = None
|
||||||
straight_length = 0
|
straight_length = 0
|
||||||
|
|
@ -1244,7 +1244,7 @@ class PathTool(Tool, metaclass=ABCMeta):
|
||||||
port_names: tuple[str, str] = ('A', 'B'),
|
port_names: tuple[str, str] = ('A', 'B'),
|
||||||
**kwargs, # noqa: ARG002 (unused)
|
**kwargs, # noqa: ARG002 (unused)
|
||||||
) -> Library:
|
) -> Library:
|
||||||
out_port, _data = self.planL(
|
out_port, dxy = self.planL(
|
||||||
ccw,
|
ccw,
|
||||||
length,
|
length,
|
||||||
in_ptype=in_ptype,
|
in_ptype=in_ptype,
|
||||||
|
|
@ -1252,12 +1252,7 @@ class PathTool(Tool, metaclass=ABCMeta):
|
||||||
)
|
)
|
||||||
|
|
||||||
tree, pat = Library.mktree(SINGLE_USE_PREFIX + 'traceL')
|
tree, pat = Library.mktree(SINGLE_USE_PREFIX + 'traceL')
|
||||||
vertices: list[tuple[float, float]]
|
pat.path(layer=self.layer, width=self.width, vertices=[(0, 0), (length, 0)])
|
||||||
if ccw is None:
|
|
||||||
vertices = [(0.0, 0.0), (length, 0.0)]
|
|
||||||
else:
|
|
||||||
vertices = [(0.0, 0.0), (length, 0.0), tuple(out_port.offset)]
|
|
||||||
pat.path(layer=self.layer, width=self.width, vertices=vertices)
|
|
||||||
|
|
||||||
if ccw is None:
|
if ccw is None:
|
||||||
out_rot = pi
|
out_rot = pi
|
||||||
|
|
@ -1268,7 +1263,7 @@ class PathTool(Tool, metaclass=ABCMeta):
|
||||||
|
|
||||||
pat.ports = {
|
pat.ports = {
|
||||||
port_names[0]: Port((0, 0), rotation=0, ptype=self.ptype),
|
port_names[0]: Port((0, 0), rotation=0, ptype=self.ptype),
|
||||||
port_names[1]: Port(out_port.offset, rotation=out_rot, ptype=self.ptype),
|
port_names[1]: Port(dxy, rotation=out_rot, ptype=self.ptype),
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree
|
return tree
|
||||||
|
|
|
||||||
|
|
@ -453,8 +453,6 @@ class Path(Shape):
|
||||||
def scale_by(self, c: float) -> 'Path':
|
def scale_by(self, c: float) -> 'Path':
|
||||||
self.vertices *= c
|
self.vertices *= c
|
||||||
self.width *= c
|
self.width *= c
|
||||||
if self.cap_extensions is not None:
|
|
||||||
self.cap_extensions *= c
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def normalized_form(self, norm_value: float) -> normalized_shape_tuple:
|
def normalized_form(self, norm_value: float) -> normalized_shape_tuple:
|
||||||
|
|
@ -478,15 +476,13 @@ class Path(Shape):
|
||||||
reordered_vertices = rotated_vertices
|
reordered_vertices = rotated_vertices
|
||||||
|
|
||||||
width0 = self.width / norm_value
|
width0 = self.width / norm_value
|
||||||
cap_extensions0 = None if self.cap_extensions is None else tuple(float(v) / norm_value for v in self.cap_extensions)
|
|
||||||
|
|
||||||
return ((type(self), reordered_vertices.data.tobytes(), width0, self.cap, cap_extensions0),
|
return ((type(self), reordered_vertices.data.tobytes(), width0, self.cap),
|
||||||
(offset, scale / norm_value, rotation, False),
|
(offset, scale / norm_value, rotation, False),
|
||||||
lambda: Path(
|
lambda: Path(
|
||||||
reordered_vertices * norm_value,
|
reordered_vertices * norm_value,
|
||||||
width=width0 * norm_value,
|
width=self.width * norm_value,
|
||||||
cap=self.cap,
|
cap=self.cap,
|
||||||
cap_extensions=None if cap_extensions0 is None else tuple(v * norm_value for v in cap_extensions0),
|
|
||||||
))
|
))
|
||||||
|
|
||||||
def clean_vertices(self) -> 'Path':
|
def clean_vertices(self) -> 'Path':
|
||||||
|
|
|
||||||
|
|
@ -108,62 +108,6 @@ def test_autotool_planS_double_L(multi_bend_tool) -> None:
|
||||||
assert data.ldata1.straight_length == 0
|
assert data.ldata1.straight_length == 0
|
||||||
assert data.l2_length == 6
|
assert data.l2_length == 6
|
||||||
|
|
||||||
|
|
||||||
def test_autotool_planS_pure_sbend_with_transition_dx() -> None:
|
|
||||||
lib = Library()
|
|
||||||
|
|
||||||
def make_straight(length: float) -> Pattern:
|
|
||||||
pat = Pattern()
|
|
||||||
pat.ports["A"] = Port((0, 0), 0, ptype="core")
|
|
||||||
pat.ports["B"] = Port((length, 0), pi, ptype="core")
|
|
||||||
return pat
|
|
||||||
|
|
||||||
def make_sbend(jog: float) -> Pattern:
|
|
||||||
pat = Pattern()
|
|
||||||
pat.ports["A"] = Port((0, 0), 0, ptype="core")
|
|
||||||
pat.ports["B"] = Port((10, jog), pi, ptype="core")
|
|
||||||
return pat
|
|
||||||
|
|
||||||
trans_pat = Pattern()
|
|
||||||
trans_pat.ports["EXT"] = Port((0, 0), 0, ptype="ext")
|
|
||||||
trans_pat.ports["CORE"] = Port((5, 0), pi, ptype="core")
|
|
||||||
lib["xin"] = trans_pat
|
|
||||||
|
|
||||||
tool = AutoTool(
|
|
||||||
straights=[
|
|
||||||
AutoTool.Straight(
|
|
||||||
ptype="core",
|
|
||||||
fn=make_straight,
|
|
||||||
in_port_name="A",
|
|
||||||
out_port_name="B",
|
|
||||||
length_range=(1, 1e8),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
bends=[],
|
|
||||||
sbends=[
|
|
||||||
AutoTool.SBend(
|
|
||||||
ptype="core",
|
|
||||||
fn=make_sbend,
|
|
||||||
in_port_name="A",
|
|
||||||
out_port_name="B",
|
|
||||||
jog_range=(0, 1e8),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
transitions={
|
|
||||||
("ext", "core"): AutoTool.Transition(lib.abstract("xin"), "EXT", "CORE"),
|
|
||||||
},
|
|
||||||
default_out_ptype="core",
|
|
||||||
)
|
|
||||||
|
|
||||||
p, data = tool.planS(15, 4, in_ptype="ext")
|
|
||||||
|
|
||||||
assert_allclose(p.offset, [15, 4])
|
|
||||||
assert_allclose(p.rotation, pi)
|
|
||||||
assert data.straight_length == 0
|
|
||||||
assert data.jog_remaining == 4
|
|
||||||
assert data.in_transition is not None
|
|
||||||
|
|
||||||
|
|
||||||
def test_renderpather_autotool_double_L(multi_bend_tool) -> None:
|
def test_renderpather_autotool_double_L(multi_bend_tool) -> None:
|
||||||
tool, lib = multi_bend_tool
|
tool, lib = multi_bend_tool
|
||||||
rp = RenderPather(lib, tools=tool)
|
rp = RenderPather(lib, tools=tool)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ from ..pattern import Pattern
|
||||||
from ..error import LibraryError, PatternError
|
from ..error import LibraryError, PatternError
|
||||||
from ..ports import Port
|
from ..ports import Port
|
||||||
from ..repetition import Grid
|
from ..repetition import Grid
|
||||||
from ..shapes import Path
|
|
||||||
from ..file.utils import preflight
|
from ..file.utils import preflight
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -244,18 +243,3 @@ def test_library_get_name() -> None:
|
||||||
|
|
||||||
name2 = lib.get_name("other")
|
name2 = lib.get_name("other")
|
||||||
assert name2 == "other"
|
assert name2 == "other"
|
||||||
|
|
||||||
|
|
||||||
def test_library_dedup_shapes_does_not_merge_custom_capped_paths() -> None:
|
|
||||||
lib = Library()
|
|
||||||
pat = Pattern()
|
|
||||||
pat.shapes[(1, 0)] += [
|
|
||||||
Path(vertices=[[0, 0], [10, 0]], width=2, cap=Path.Cap.SquareCustom, cap_extensions=(1, 2)),
|
|
||||||
Path(vertices=[[20, 0], [30, 0]], width=2, cap=Path.Cap.SquareCustom, cap_extensions=(3, 4)),
|
|
||||||
]
|
|
||||||
lib["top"] = pat
|
|
||||||
|
|
||||||
lib.dedup(norm_value=1, threshold=2)
|
|
||||||
|
|
||||||
assert not lib["top"].refs
|
|
||||||
assert len(lib["top"].shapes[(1, 0)]) == 2
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from ..utils.pack2d import maxrects_bssf, guillotine_bssf_sas, pack_patterns
|
from ..utils.pack2d import maxrects_bssf, pack_patterns
|
||||||
from ..library import Library
|
from ..library import Library
|
||||||
from ..pattern import Pattern
|
from ..pattern import Pattern
|
||||||
|
|
||||||
|
|
@ -25,34 +25,6 @@ def test_maxrects_bssf_reject() -> None:
|
||||||
assert 0 not in rejects
|
assert 0 not in rejects
|
||||||
|
|
||||||
|
|
||||||
def test_maxrects_bssf_exact_fill_rejects_remaining() -> None:
|
|
||||||
rects = [[20, 20], [1, 1]]
|
|
||||||
containers = [[0, 0, 20, 20]]
|
|
||||||
|
|
||||||
locs, rejects = maxrects_bssf(rects, containers, presort=False, allow_rejects=True)
|
|
||||||
|
|
||||||
assert tuple(locs[0]) == (0.0, 0.0)
|
|
||||||
assert rejects == {1}
|
|
||||||
|
|
||||||
|
|
||||||
def test_maxrects_bssf_presort_reject_mapping() -> None:
|
|
||||||
rects = [[10, 12], [19, 14], [13, 11]]
|
|
||||||
containers = [[0, 0, 20, 20]]
|
|
||||||
|
|
||||||
_locs, rejects = maxrects_bssf(rects, containers, presort=True, allow_rejects=True)
|
|
||||||
|
|
||||||
assert rejects == {0, 2}
|
|
||||||
|
|
||||||
|
|
||||||
def test_guillotine_bssf_sas_presort_reject_mapping() -> None:
|
|
||||||
rects = [[2, 1], [17, 15], [16, 11]]
|
|
||||||
containers = [[0, 0, 20, 20]]
|
|
||||||
|
|
||||||
_locs, rejects = guillotine_bssf_sas(rects, containers, presort=True, allow_rejects=True)
|
|
||||||
|
|
||||||
assert rejects == {2}
|
|
||||||
|
|
||||||
|
|
||||||
def test_pack_patterns() -> None:
|
def test_pack_patterns() -> None:
|
||||||
lib = Library()
|
lib = Library()
|
||||||
p1 = Pattern()
|
p1 = Pattern()
|
||||||
|
|
@ -77,20 +49,3 @@ def test_pack_patterns() -> None:
|
||||||
# p1 size 10x10, effectively 12x12
|
# p1 size 10x10, effectively 12x12
|
||||||
# p2 size 5x5, effectively 7x7
|
# p2 size 5x5, effectively 7x7
|
||||||
# Both should fit in 20x20
|
# Both should fit in 20x20
|
||||||
|
|
||||||
|
|
||||||
def test_pack_patterns_reject_names_match_original_patterns() -> None:
|
|
||||||
lib = Library()
|
|
||||||
for name, (lx, ly) in {
|
|
||||||
"p0": (10, 12),
|
|
||||||
"p1": (19, 14),
|
|
||||||
"p2": (13, 11),
|
|
||||||
}.items():
|
|
||||||
pat = Pattern()
|
|
||||||
pat.rect((1, 0), xmin=0, xmax=lx, ymin=0, ymax=ly)
|
|
||||||
lib[name] = pat
|
|
||||||
|
|
||||||
pat, rejects = pack_patterns(lib, ["p0", "p1", "p2"], [[0, 0, 20, 20]], spacing=(0, 0))
|
|
||||||
|
|
||||||
assert set(rejects) == {"p0", "p2"}
|
|
||||||
assert set(pat.refs) == {"p1"}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from numpy.testing import assert_equal, assert_allclose
|
from numpy.testing import assert_equal
|
||||||
|
|
||||||
from ..shapes import Path
|
from ..shapes import Path
|
||||||
|
|
||||||
|
|
@ -79,33 +79,3 @@ def test_path_scale() -> None:
|
||||||
p.scale_by(2)
|
p.scale_by(2)
|
||||||
assert_equal(p.vertices, [[0, 0], [20, 0]])
|
assert_equal(p.vertices, [[0, 0], [20, 0]])
|
||||||
assert p.width == 4
|
assert p.width == 4
|
||||||
|
|
||||||
|
|
||||||
def test_path_scale_custom_cap_extensions() -> None:
|
|
||||||
p = Path(vertices=[[0, 0], [10, 0]], width=2, cap=Path.Cap.SquareCustom, cap_extensions=(1, 2))
|
|
||||||
p.scale_by(3)
|
|
||||||
|
|
||||||
assert_equal(p.vertices, [[0, 0], [30, 0]])
|
|
||||||
assert p.width == 6
|
|
||||||
assert p.cap_extensions is not None
|
|
||||||
assert_allclose(p.cap_extensions, [3, 6])
|
|
||||||
assert_equal(p.to_polygons()[0].get_bounds_single(), [[-3, -3], [36, 3]])
|
|
||||||
|
|
||||||
|
|
||||||
def test_path_normalized_form_preserves_width_and_custom_cap_extensions() -> None:
|
|
||||||
p = Path(vertices=[[0, 0], [10, 0]], width=2, cap=Path.Cap.SquareCustom, cap_extensions=(1, 2))
|
|
||||||
|
|
||||||
intrinsic, _extrinsic, ctor = p.normalized_form(5)
|
|
||||||
q = ctor()
|
|
||||||
|
|
||||||
assert intrinsic[-1] == (0.2, 0.4)
|
|
||||||
assert q.width == 2
|
|
||||||
assert q.cap_extensions is not None
|
|
||||||
assert_allclose(q.cap_extensions, [1, 2])
|
|
||||||
|
|
||||||
|
|
||||||
def test_path_normalized_form_distinguishes_custom_caps() -> None:
|
|
||||||
p1 = Path(vertices=[[0, 0], [10, 0]], width=2, cap=Path.Cap.SquareCustom, cap_extensions=(1, 2))
|
|
||||||
p2 = Path(vertices=[[0, 0], [10, 0]], width=2, cap=Path.Cap.SquareCustom, cap_extensions=(3, 4))
|
|
||||||
|
|
||||||
assert p1.normalized_form(1)[0] != p2.normalized_form(1)[0]
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import pytest
|
|
||||||
import numpy
|
import numpy
|
||||||
from numpy import pi
|
from numpy import pi
|
||||||
from masque import Pather, RenderPather, Library, Pattern, Port
|
from masque import Pather, RenderPather, Library, Pattern, Port
|
||||||
from masque.builder.tools import PathTool
|
from masque.builder.tools import PathTool
|
||||||
from masque.error import BuildError
|
|
||||||
|
|
||||||
def test_pather_trace_basic() -> None:
|
def test_pather_trace_basic() -> None:
|
||||||
lib = Library()
|
lib = Library()
|
||||||
|
|
@ -242,31 +240,3 @@ def test_pather_trace_into() -> None:
|
||||||
assert numpy.allclose(p.pattern.ports['G'].offset, (-10000, 2000))
|
assert numpy.allclose(p.pattern.ports['G'].offset, (-10000, 2000))
|
||||||
assert p.pattern.ports['G'].rotation is not None
|
assert p.pattern.ports['G'].rotation is not None
|
||||||
assert numpy.isclose(p.pattern.ports['G'].rotation, pi)
|
assert numpy.isclose(p.pattern.ports['G'].rotation, pi)
|
||||||
|
|
||||||
|
|
||||||
def test_pather_jog_failed_fallback_is_atomic() -> None:
|
|
||||||
lib = Library()
|
|
||||||
tool = PathTool(layer='M1', width=2, ptype='wire')
|
|
||||||
p = Pather(lib, tools=tool)
|
|
||||||
p.pattern.ports['A'] = Port((0, 0), rotation=0, ptype='wire')
|
|
||||||
|
|
||||||
with pytest.raises(BuildError, match='shorter than required bend'):
|
|
||||||
p.jog('A', 1.5, length=5)
|
|
||||||
|
|
||||||
assert numpy.allclose(p.pattern.ports['A'].offset, (0, 0))
|
|
||||||
assert p.pattern.ports['A'].rotation == 0
|
|
||||||
assert len(p.paths['A']) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_pather_uturn_failed_fallback_is_atomic() -> None:
|
|
||||||
lib = Library()
|
|
||||||
tool = PathTool(layer='M1', width=2, ptype='wire')
|
|
||||||
p = Pather(lib, tools=tool)
|
|
||||||
p.pattern.ports['A'] = Port((0, 0), rotation=0, ptype='wire')
|
|
||||||
|
|
||||||
with pytest.raises(BuildError, match='shorter than required bend'):
|
|
||||||
p.uturn('A', 1.5, length=0)
|
|
||||||
|
|
||||||
assert numpy.allclose(p.pattern.ports['A'].offset, (0, 0))
|
|
||||||
assert p.pattern.ports['A'].rotation == 0
|
|
||||||
assert len(p.paths['A']) == 0
|
|
||||||
|
|
|
||||||
|
|
@ -119,14 +119,3 @@ def test_renderpather_rename_port(rpather_setup: tuple[RenderPather, PathTool, L
|
||||||
assert_allclose(path_shape.vertices, [[0, 0], [0, -10], [0, -20]], atol=1e-10)
|
assert_allclose(path_shape.vertices, [[0, 0], [0, -10], [0, -20]], atol=1e-10)
|
||||||
assert "new_start" in rp.ports
|
assert "new_start" in rp.ports
|
||||||
assert_allclose(rp.ports["new_start"].offset, [0, -20], atol=1e-10)
|
assert_allclose(rp.ports["new_start"].offset, [0, -20], atol=1e-10)
|
||||||
|
|
||||||
|
|
||||||
def test_pathtool_traceL_bend_geometry_matches_ports() -> None:
|
|
||||||
tool = PathTool(layer=(1, 0), width=2, ptype="wire")
|
|
||||||
|
|
||||||
tree = tool.traceL(True, 10)
|
|
||||||
pat = tree.top_pattern()
|
|
||||||
path_shape = cast("Path", pat.shapes[(1, 0)][0])
|
|
||||||
|
|
||||||
assert_allclose(path_shape.vertices, [[0, 0], [10, 0], [10, 1]], atol=1e-10)
|
|
||||||
assert_allclose(pat.ports["B"].offset, [10, 1], atol=1e-10)
|
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,6 @@ def maxrects_bssf(
|
||||||
degenerate = (min_more & max_less).any(axis=0)
|
degenerate = (min_more & max_less).any(axis=0)
|
||||||
regions = regions[~degenerate]
|
regions = regions[~degenerate]
|
||||||
|
|
||||||
if regions.shape[0] == 0:
|
|
||||||
if allow_rejects:
|
|
||||||
rejected_inds.add(rect_ind)
|
|
||||||
continue
|
|
||||||
raise MasqueError(f'Failed to find a suitable location for rectangle {rect_ind}')
|
|
||||||
|
|
||||||
''' Place the rect '''
|
''' Place the rect '''
|
||||||
# Best short-side fit (bssf) to pick a region
|
# Best short-side fit (bssf) to pick a region
|
||||||
region_sizes = regions[:, 2:] - regions[:, :2]
|
region_sizes = regions[:, 2:] - regions[:, :2]
|
||||||
|
|
@ -108,7 +102,7 @@ def maxrects_bssf(
|
||||||
if presort:
|
if presort:
|
||||||
unsort_order = rect_order.argsort()
|
unsort_order = rect_order.argsort()
|
||||||
rect_locs = rect_locs[unsort_order]
|
rect_locs = rect_locs[unsort_order]
|
||||||
rejected_inds = {int(rect_order[ii]) for ii in rejected_inds}
|
rejected_inds = set(unsort_order[list(rejected_inds)])
|
||||||
|
|
||||||
return rect_locs, rejected_inds
|
return rect_locs, rejected_inds
|
||||||
|
|
||||||
|
|
@ -193,7 +187,7 @@ def guillotine_bssf_sas(
|
||||||
if presort:
|
if presort:
|
||||||
unsort_order = rect_order.argsort()
|
unsort_order = rect_order.argsort()
|
||||||
rect_locs = rect_locs[unsort_order]
|
rect_locs = rect_locs[unsort_order]
|
||||||
rejected_inds = {int(rect_order[ii]) for ii in rejected_inds}
|
rejected_inds = set(unsort_order[list(rejected_inds)])
|
||||||
|
|
||||||
return rect_locs, rejected_inds
|
return rect_locs, rejected_inds
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue