Add item hierarchy, BasicBoard, and DSN->board construction
Ports the data model of the board Item hierarchy (Item base, Pin, ObstacleArea/ConductionArea, Via, Trace) and BasicBoard (layers, nets, clearance, bounding box, items with query helpers), then build_board: the load-bearing integration that constructs a BasicBoard from a parsed DsnBoard. build_board maps layers -> LayerStructure, resolution -> transform, default clearance rule -> ClearanceMatrix, nets -> Nets plus a (component,pin)->net map, padstacks x placement -> Pin items, and keepouts -> ObstacleArea items. Rectangle pads become exact IntBoxes, convex polygon pads exact Simplexes, circle pads their bounding box (documented approximation); every pad is centred on its pin location so it contains that location by construction. Trace/Via are router-produced and lightweight here (an imported unrouted board has none). Validated on a real KiCad export (kicad_routable.dsn): layer/net/pin counts match the parsed DSN, every pin's pad shape contains its origin, every pin reports a valid net, and pin locations lie in the board bounding box. An oracle-gated test cross-checks that every net the reference FreeRouting JAR routes exists on the constructed board.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
"""``BasicBoard`` — the board container.
|
||||
|
||||
Ports the data-model core of ``board/BasicBoard.java``: the layer stack, the
|
||||
net list, the clearance matrix, the bounding box, and the list of items with
|
||||
insertion and query helpers. The routing operations live in ``RoutingBoard``
|
||||
(the router phase); this class is what DSN import produces and what the
|
||||
board-model invariants check.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from freeroute.geometry import IntBox
|
||||
|
||||
from .clearance import ClearanceMatrix
|
||||
from .items import Item, ObstacleArea, Pin, Trace, Via
|
||||
from .layer import LayerStructure
|
||||
from .net import Nets
|
||||
|
||||
__all__ = ["BasicBoard"]
|
||||
|
||||
|
||||
class BasicBoard:
|
||||
"""A board: layers, nets, clearances, a bounding box, and items."""
|
||||
|
||||
__slots__ = ("layer_structure", "nets", "clearance_matrix", "bounding_box", "_items")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
layer_structure: LayerStructure,
|
||||
nets: Nets,
|
||||
clearance_matrix: ClearanceMatrix,
|
||||
bounding_box: IntBox,
|
||||
) -> None:
|
||||
self.layer_structure = layer_structure
|
||||
self.nets = nets
|
||||
self.clearance_matrix = clearance_matrix
|
||||
self.bounding_box = bounding_box
|
||||
self._items: list[Item] = []
|
||||
|
||||
# --- layers -------------------------------------------------------------
|
||||
|
||||
def get_layer_count(self) -> int:
|
||||
return len(self.layer_structure)
|
||||
|
||||
# --- items --------------------------------------------------------------
|
||||
|
||||
def insert(self, item: Item) -> Item:
|
||||
self._items.append(item)
|
||||
return item
|
||||
|
||||
def get_items(self) -> list[Item]:
|
||||
return list(self._items)
|
||||
|
||||
def get_pins(self) -> list[Pin]:
|
||||
return [it for it in self._items if isinstance(it, Pin)]
|
||||
|
||||
def get_obstacle_areas(self) -> list[ObstacleArea]:
|
||||
return [it for it in self._items if isinstance(it, ObstacleArea)]
|
||||
|
||||
def get_traces(self) -> list[Trace]:
|
||||
return [it for it in self._items if isinstance(it, Trace)]
|
||||
|
||||
def get_vias(self) -> list[Via]:
|
||||
return [it for it in self._items if isinstance(it, Via)]
|
||||
|
||||
def get_connectable_items(self, net_no: int) -> list[Item]:
|
||||
return [it for it in self._items if it.contains_net(net_no)]
|
||||
|
||||
def item_count(self) -> int:
|
||||
return len(self._items)
|
||||
Reference in New Issue
Block a user