[Pather / planner / ports] improve trace_into connection accuracy
This commit is contained in:
parent
e397b3f96e
commit
2b6782c93e
4 changed files with 35 additions and 8 deletions
|
|
@ -32,7 +32,6 @@ from __future__ import annotations
|
|||
from collections.abc import Iterable, Mapping, Sequence
|
||||
from dataclasses import dataclass, replace
|
||||
from itertools import combinations
|
||||
from math import cos, sin
|
||||
from typing import Any, Literal
|
||||
|
||||
import numpy
|
||||
|
|
@ -41,7 +40,7 @@ from numpy.typing import ArrayLike
|
|||
|
||||
from ...error import BuildError, PortError
|
||||
from ...ports import Port
|
||||
from ...utils import PTypeMatch, SupportsBool, ptype_match, ptypes_compatible
|
||||
from ...utils import PTypeMatch, SupportsBool, ptype_match, ptypes_compatible, rotation_matrix_2d
|
||||
from ..tools import (
|
||||
BendOffer,
|
||||
PrimitiveKind,
|
||||
|
|
@ -579,10 +578,11 @@ class Solver:
|
|||
out_port = step.out_port
|
||||
if out_port.rotation is None:
|
||||
raise ToolContractError('Primitive endpoints must have rotation')
|
||||
angle_cos = cos(angle)
|
||||
angle_sin = sin(angle)
|
||||
x += angle_cos * float(out_port.x) - angle_sin * float(out_port.y)
|
||||
y += angle_sin * float(out_port.x) + angle_cos * float(out_port.y)
|
||||
rotation = rotation_matrix_2d(angle)
|
||||
out_x = float(out_port.x)
|
||||
out_y = float(out_port.y)
|
||||
x += rotation[0, 0] * out_x + rotation[0, 1] * out_y
|
||||
y += rotation[1, 0] * out_x + rotation[1, 1] * out_y
|
||||
angle += out_port.rotation + pi
|
||||
ptype = out_port.ptype
|
||||
return Port((x, y), rotation=angle - pi, ptype=ptype)
|
||||
|
|
|
|||
|
|
@ -574,10 +574,10 @@ class PortList(metaclass=ABCMeta):
|
|||
raise PortError(msg)
|
||||
|
||||
translations = a_offsets - b_offsets
|
||||
if not numpy.allclose(translations, 0):
|
||||
if not numpy.allclose(a_offsets, b_offsets):
|
||||
msg = 'Port translations do not match:\n'
|
||||
for nn, (kk, vv) in enumerate(connections.items()):
|
||||
if not numpy.allclose(translations[nn], 0):
|
||||
if not numpy.allclose(a_offsets[nn], b_offsets[nn]):
|
||||
msg += f'{kk} | {translations[nn]} | {vv}\n'
|
||||
raise PortError(msg)
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,22 @@ def test_pather_trace_into_shapes() -> None:
|
|||
assert numpy.isclose(p.pattern.ports['I'].rotation, pi / 2)
|
||||
|
||||
|
||||
def test_pather_trace_into_large_composed_manhattan_route_plugs() -> None:
|
||||
p = Pather(
|
||||
Library(),
|
||||
tools=PathTool(layer='M1', width=1000, ptype='wire'),
|
||||
render='deferred',
|
||||
)
|
||||
p.ports['src'] = Port((123.25, 456.75), rotation=0, ptype='wire')
|
||||
p.ports['dst'] = Port((-99_999_876.75, 20_000_456.75), rotation=0, ptype='wire')
|
||||
|
||||
p.trace_into('src', 'dst')
|
||||
|
||||
assert 'src' not in p.ports
|
||||
assert 'dst' not in p.ports
|
||||
assert [step.kind for step in p._paths['src']] == ['straight', 'bend', 'straight', 'bend', 'plug']
|
||||
|
||||
|
||||
def test_pather_trace_into_refines_output_adapter_route_before_plug() -> None:
|
||||
class TransitionTool(Tool):
|
||||
def primitive_offers(
|
||||
|
|
|
|||
|
|
@ -169,6 +169,17 @@ def test_port_list_plugged() -> None:
|
|||
assert not pl.ports # Both should be removed
|
||||
|
||||
|
||||
def test_port_list_plugged_uses_coordinate_relative_tolerance() -> None:
|
||||
pattern = Pattern(ports={
|
||||
"A": Port((10, 10), 0),
|
||||
"B": Port((10 + 5e-8, 10), pi),
|
||||
})
|
||||
|
||||
pattern.plugged({"A": "B"})
|
||||
|
||||
assert not pattern.ports
|
||||
|
||||
|
||||
def test_port_list_plugged_ptype_compatibility_warnings(caplog: pytest.LogCaptureFixture) -> None:
|
||||
caplog.set_level("WARNING", logger="masque.ports")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue