[Pather] make two-L path planning atomic (don't error out with only one half drawn)
This commit is contained in:
parent
3beadd2bf0
commit
e7f847d4c7
2 changed files with 45 additions and 4 deletions
|
|
@ -415,8 +415,17 @@ 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
|
||||||
|
|
||||||
self._traceL(portspec, ccw0, L1, **(kwargs | {'out_ptype': None}))
|
try:
|
||||||
self._traceL(portspec, not ccw0, L2, **(kwargs | {'plug_into': plug_into}))
|
out_port0, data0 = tool.planL(ccw0, L1, in_ptype=in_ptype, **(kwargs | {'out_ptype': None}))
|
||||||
|
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)
|
||||||
|
|
@ -436,14 +445,16 @@ 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
|
||||||
self._traceL(portspec, ccw, L1, **(kwargs | {'out_ptype': None}))
|
out_port0, data0 = tool.planL(ccw, L1, in_ptype=in_ptype, **(kwargs | {'out_ptype': None}))
|
||||||
self._traceL(portspec, ccw, L2, **(kwargs | {'plug_into': plug_into}))
|
out_port1, data1 = tool.planL(ccw, L2, in_ptype=out_port0.ptype, **kwargs)
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
|
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()
|
||||||
|
|
@ -240,3 +242,31 @@ 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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue