diff --git a/lib/fixtures/twoNodeExpansionFixture.ts b/lib/fixtures/twoNodeExpansionFixture.ts index 8da9553..f6e24d5 100644 --- a/lib/fixtures/twoNodeExpansionFixture.ts +++ b/lib/fixtures/twoNodeExpansionFixture.ts @@ -2,7 +2,7 @@ import RBush from "rbush" import type { RectDiffExpansionSolverInput } from "../solvers/RectDiffExpansionSolver/RectDiffExpansionSolver" import type { SimpleRouteJson } from "../types/srj-types" import type { XYRect } from "../rectdiff-types" -import type { RTreeRect } from "lib/types/capacity-mesh-types" +import type { RTreeRect } from "../types/capacity-mesh-types" import { buildZIndexMap } from "../solvers/RectDiffSeedingSolver/layers" /** diff --git a/lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts b/lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts index fb21c92..e54dde0 100644 --- a/lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts +++ b/lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts @@ -1,5 +1,5 @@ import { BaseSolver } from "@tscircuit/solver-utils" -import type { CapacityMeshNode } from "lib/types/capacity-mesh-types" +import type { CapacityMeshNode } from "../../types/capacity-mesh-types" import type { SegmentWithAdjacentEmptySpace } from "./FindSegmentsWithAdjacentEmptySpaceSolver" import type { GraphicsObject } from "graphics-debug" import RBush from "rbush" @@ -7,7 +7,7 @@ import { EDGE_MAP, EDGES } from "./edge-constants" import { getBoundsFromCorners } from "./getBoundsFromCorners" import type { Bounds } from "@tscircuit/math-utils" import { midpoint, segmentToBoxMinDistance } from "@tscircuit/math-utils" -import type { XYRect } from "lib/rectdiff-types" +import type { XYRect } from "../../rectdiff-types" const EPS = 1e-4 @@ -212,6 +212,8 @@ export class ExpandEdgesToEmptySpaceSolver extends BaseSolver { rects: [], points: [], lines: [], + infiniteLines: [], + polygons: [], circles: [], arrows: [], texts: [], diff --git a/lib/solvers/GapFillSolver/FindSegmentsWithAdjacentEmptySpaceSolver.ts b/lib/solvers/GapFillSolver/FindSegmentsWithAdjacentEmptySpaceSolver.ts index a6280aa..cb2c91f 100644 --- a/lib/solvers/GapFillSolver/FindSegmentsWithAdjacentEmptySpaceSolver.ts +++ b/lib/solvers/GapFillSolver/FindSegmentsWithAdjacentEmptySpaceSolver.ts @@ -1,7 +1,7 @@ import { BaseSolver } from "@tscircuit/solver-utils" import Flatbush from "flatbush" import type { GraphicsObject, NinePointAnchor } from "graphics-debug" -import type { CapacityMeshNode } from "lib/types/capacity-mesh-types" +import type { CapacityMeshNode } from "../../types/capacity-mesh-types" import { projectToUncoveredSegments } from "./projectToUncoveredSegments" import { EDGES } from "./edge-constants" import { visuallyOffsetLine } from "./visuallyOffsetLine" @@ -139,6 +139,8 @@ export class FindSegmentsWithAdjacentEmptySpaceSolver extends BaseSolver { rects: [], points: [], lines: [], + infiniteLines: [], + polygons: [], circles: [], arrows: [], texts: [], diff --git a/lib/solvers/GapFillSolver/GapFillSolverPipeline.ts b/lib/solvers/GapFillSolver/GapFillSolverPipeline.ts index cb2e231..b2655c2 100644 --- a/lib/solvers/GapFillSolver/GapFillSolverPipeline.ts +++ b/lib/solvers/GapFillSolver/GapFillSolverPipeline.ts @@ -3,11 +3,11 @@ import { definePipelineStep, type PipelineStep, } from "@tscircuit/solver-utils" -import type { CapacityMeshNode } from "lib/types/capacity-mesh-types" +import type { CapacityMeshNode } from "../../types/capacity-mesh-types" import type { GraphicsObject } from "graphics-debug" import { FindSegmentsWithAdjacentEmptySpaceSolver } from "./FindSegmentsWithAdjacentEmptySpaceSolver" import { ExpandEdgesToEmptySpaceSolver } from "./ExpandEdgesToEmptySpaceSolver" -import type { XYRect } from "lib/rectdiff-types" +import type { XYRect } from "../../rectdiff-types" type GapFillSolverInput = { meshNodes: CapacityMeshNode[] @@ -73,6 +73,8 @@ export class GapFillSolverPipeline extends BasePipelineSolver Math.round(value / precision) * precision diff --git a/lib/solvers/RectDiffSeedingSolver/computeEdgeCandidates3D.ts b/lib/solvers/RectDiffSeedingSolver/computeEdgeCandidates3D.ts index 7500c55..f106d59 100644 --- a/lib/solvers/RectDiffSeedingSolver/computeEdgeCandidates3D.ts +++ b/lib/solvers/RectDiffSeedingSolver/computeEdgeCandidates3D.ts @@ -3,7 +3,7 @@ import { EPS, distancePointToRectEdges } from "../../utils/rectdiff-geometry" import { isFullyOccupiedAtPoint } from "../../utils/isFullyOccupiedAtPoint" import { longestFreeSpanAroundZ } from "./longestFreeSpanAroundZ" import type RBush from "rbush" -import type { RTreeRect } from "lib/types/capacity-mesh-types" +import type { RTreeRect } from "../../types/capacity-mesh-types" const quantize = (value: number, precision = 1e-6) => Math.round(value / precision) * precision diff --git a/lib/solvers/RectDiffSeedingSolver/longestFreeSpanAroundZ.ts b/lib/solvers/RectDiffSeedingSolver/longestFreeSpanAroundZ.ts index 9e08f84..acd8db8 100644 --- a/lib/solvers/RectDiffSeedingSolver/longestFreeSpanAroundZ.ts +++ b/lib/solvers/RectDiffSeedingSolver/longestFreeSpanAroundZ.ts @@ -1,4 +1,4 @@ -import type { RTreeRect } from "lib/types/capacity-mesh-types" +import type { RTreeRect } from "../../types/capacity-mesh-types" import type { XYRect } from "../../rectdiff-types" import { clamp, containsPoint } from "../../utils/rectdiff-geometry" import type RBush from "rbush" diff --git a/lib/types/capacity-mesh-types.ts b/lib/types/capacity-mesh-types.ts index 2beae8b..dc4bdd4 100644 --- a/lib/types/capacity-mesh-types.ts +++ b/lib/types/capacity-mesh-types.ts @@ -1,4 +1,4 @@ -import type { XYRect } from "lib/rectdiff-types" +import type { XYRect } from "../rectdiff-types" export type CapacityMeshNodeId = string diff --git a/lib/utils/expandRectFromSeed.ts b/lib/utils/expandRectFromSeed.ts index 34dd1c8..9285330 100644 --- a/lib/utils/expandRectFromSeed.ts +++ b/lib/utils/expandRectFromSeed.ts @@ -1,7 +1,7 @@ import type RBush from "rbush" import type { XYRect } from "../rectdiff-types" import { EPS, gt, gte, lt, lte, overlaps } from "./rectdiff-geometry" -import type { RTreeRect } from "lib/types/capacity-mesh-types" +import type { RTreeRect } from "../types/capacity-mesh-types" import { isSelfRect } from "./isSelfRect" import { searchStripDown, diff --git a/lib/utils/finalizeRects.ts b/lib/utils/finalizeRects.ts index 2cf12a5..da3dd55 100644 --- a/lib/utils/finalizeRects.ts +++ b/lib/utils/finalizeRects.ts @@ -1,4 +1,4 @@ -import type { Obstacle } from "lib/types/srj-types" +import type { Obstacle } from "../types/srj-types" import type { Placed3D, Rect3d, XYRect } from "../rectdiff-types" import { obstacleToXYRect, diff --git a/lib/utils/isFullyOccupiedAtPoint.ts b/lib/utils/isFullyOccupiedAtPoint.ts index 988e5e1..c90d8ca 100644 --- a/lib/utils/isFullyOccupiedAtPoint.ts +++ b/lib/utils/isFullyOccupiedAtPoint.ts @@ -1,4 +1,4 @@ -import type { RTreeRect } from "lib/types/capacity-mesh-types" +import type { RTreeRect } from "../types/capacity-mesh-types" import RBush from "rbush" export type OccupancyParams = { diff --git a/lib/utils/isSelfRect.ts b/lib/utils/isSelfRect.ts index 2eb841f..55be7fb 100644 --- a/lib/utils/isSelfRect.ts +++ b/lib/utils/isSelfRect.ts @@ -1,4 +1,4 @@ -import type { XYRect } from "lib/rectdiff-types" +import type { XYRect } from "../rectdiff-types" const EPS = 1e-9 diff --git a/lib/utils/rectToTree.ts b/lib/utils/rectToTree.ts index e191a6c..6b68f76 100644 --- a/lib/utils/rectToTree.ts +++ b/lib/utils/rectToTree.ts @@ -1,5 +1,5 @@ -import type { XYRect } from "lib/rectdiff-types" -import type { RTreeRect } from "lib/types/capacity-mesh-types" +import type { XYRect } from "../rectdiff-types" +import type { RTreeRect } from "../types/capacity-mesh-types" export const rectToTree = ( rect: XYRect, diff --git a/lib/utils/renderObstacleClearance.ts b/lib/utils/renderObstacleClearance.ts index b780fdd..e9ea4d0 100644 --- a/lib/utils/renderObstacleClearance.ts +++ b/lib/utils/renderObstacleClearance.ts @@ -1,4 +1,4 @@ -import type { SimpleRouteJson } from "lib/types/srj-types" +import type { SimpleRouteJson } from "../types/srj-types" import type { GraphicsObject } from "graphics-debug" /** diff --git a/lib/utils/resizeSoftOverlaps.ts b/lib/utils/resizeSoftOverlaps.ts index ce52ad5..87a19e5 100644 --- a/lib/utils/resizeSoftOverlaps.ts +++ b/lib/utils/resizeSoftOverlaps.ts @@ -1,4 +1,4 @@ -import type { RTreeRect } from "lib/types/capacity-mesh-types" +import type { RTreeRect } from "../types/capacity-mesh-types" import type { Placed3D } from "../rectdiff-types" import { overlaps, subtractRect2D, EPS } from "./rectdiff-geometry" import type RBush from "rbush" diff --git a/lib/utils/sameTreeRect.ts b/lib/utils/sameTreeRect.ts index ecf2fec..508fd1c 100644 --- a/lib/utils/sameTreeRect.ts +++ b/lib/utils/sameTreeRect.ts @@ -1,4 +1,4 @@ -import type { RTreeRect } from "lib/types/capacity-mesh-types" +import type { RTreeRect } from "../types/capacity-mesh-types" export const sameTreeRect = (a: RTreeRect, b: RTreeRect) => a.minX === b.minX && diff --git a/lib/utils/searchStrip.ts b/lib/utils/searchStrip.ts index d7adecd..45f6882 100644 --- a/lib/utils/searchStrip.ts +++ b/lib/utils/searchStrip.ts @@ -1,4 +1,4 @@ -import type { XYRect } from "lib/rectdiff-types" +import type { XYRect } from "../rectdiff-types" export const searchStripRight = ({ rect, diff --git a/package.json b/package.json index 6965712..9d379f8 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,11 @@ "name": "@tscircuit/rectdiff", "version": "0.0.25", "type": "module", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "./lib/index.ts", + "types": "./lib/index.ts", + "exports": { + ".": "./lib/index.ts" + }, "scripts": { "start": "cosmos", "build": "tsup-node ./lib/index.ts --format esm --dts", @@ -16,7 +19,7 @@ "@biomejs/biome": "^2.3.5", "@react-hook/resize-observer": "^2.0.2", "@tscircuit/math-utils": "^0.0.29", - "@tscircuit/solver-utils": "^0.0.9", + "@tscircuit/solver-utils": "^0.0.16", "@types/bun": "latest", "@types/rbush": "^4.0.0", "@types/react": "^18", @@ -25,7 +28,7 @@ "@vitejs/plugin-react": "^4", "biome": "^0.3.3", "bun-match-svg": "^0.0.14", - "graphics-debug": "^0.0.76", + "graphics-debug": "^0.0.90", "rbush": "^4.0.1", "react": "18", "react-cosmos": "^6.2.3", diff --git a/tests/solver/pour-via-escape-06/__snapshots__/pour-via-escape-06.snap.svg b/tests/solver/pour-via-escape-06/__snapshots__/pour-via-escape-06.snap.svg new file mode 100644 index 0000000..00f992f --- /dev/null +++ b/tests/solver/pour-via-escape-06/__snapshots__/pour-via-escape-06.snap.svg @@ -0,0 +1,44 @@ +Layer z=0Layer z=1Layer z=2Layer z=3 \ No newline at end of file diff --git a/tests/solver/pour-via-escape-06/pour-via-escape-06.json b/tests/solver/pour-via-escape-06/pour-via-escape-06.json new file mode 100644 index 0000000..c8bb5d9 --- /dev/null +++ b/tests/solver/pour-via-escape-06/pour-via-escape-06.json @@ -0,0 +1,861 @@ +[ + { + "simpleRouteJson": { + "bounds": { "maxX": 10, "maxY": 5, "minX": -10, "minY": -5 }, + "obstacles": [ + { + "type": "rect", + "width": 1, + "center": { "x": -2.15, "y": 2.54 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_0", + "connectivity_net8", + "source_trace_3", + "source_port_10", + "source_port_0", + "pcb_smtpad_0", + "pcb_port_0", + "pcb_smtpad_10", + "pcb_port_10" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": -2.15, "y": 1.27 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_1", + "connectivity_net26", + "source_trace_10", + "source_port_17", + "source_trace_6", + "source_port_13", + "source_trace_4", + "source_port_11", + "source_trace_2", + "source_port_3", + "source_trace_0", + "source_port_1", + "source_net_0", + "pcb_smtpad_1", + "pcb_port_1", + "pcb_smtpad_3", + "pcb_port_3", + "pcb_smtpad_11", + "pcb_port_11", + "pcb_smtpad_13", + "pcb_port_13", + "pcb_smtpad_17", + "pcb_port_17" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": -2.15, "y": 0 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_2", + "connectivity_net24", + "source_trace_9", + "source_port_16", + "source_trace_1", + "source_port_2", + "source_net_1", + "pcb_smtpad_2", + "pcb_port_2", + "pcb_smtpad_16", + "pcb_port_16" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": -2.15, "y": -1.27 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_3", + "connectivity_net26", + "source_trace_10", + "source_port_17", + "source_trace_6", + "source_port_13", + "source_trace_4", + "source_port_11", + "source_trace_2", + "source_port_3", + "source_trace_0", + "source_port_1", + "source_net_0", + "pcb_smtpad_1", + "pcb_port_1", + "pcb_smtpad_3", + "pcb_port_3", + "pcb_smtpad_11", + "pcb_port_11", + "pcb_smtpad_13", + "pcb_port_13", + "pcb_smtpad_17", + "pcb_port_17" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": -2.15, "y": -2.54 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_4", + "connectivity_net74", + "source_port_4", + "pcb_smtpad_4", + "pcb_port_4" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 2.15, "y": -2.54 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_5", + "connectivity_net13", + "source_trace_5", + "source_port_12", + "source_port_5", + "pcb_smtpad_5", + "pcb_port_5", + "pcb_smtpad_12", + "pcb_port_12" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 2.15, "y": -1.27 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_6", + "connectivity_net21", + "source_trace_8", + "source_port_15", + "source_port_6", + "pcb_smtpad_6", + "pcb_port_6", + "pcb_smtpad_15", + "pcb_port_15" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 2.15, "y": 0 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_7", + "connectivity_net18", + "source_trace_7", + "source_port_14", + "source_port_7", + "pcb_smtpad_7", + "pcb_port_7", + "pcb_smtpad_14", + "pcb_port_14" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 2.15, "y": 1.27 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_8", + "connectivity_net31", + "source_trace_12", + "source_port_19", + "source_port_8", + "pcb_smtpad_8", + "pcb_port_8", + "pcb_smtpad_19", + "pcb_port_19" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 2.15, "y": 2.54 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_9", + "connectivity_net28", + "source_trace_11", + "source_port_18", + "source_port_9", + "pcb_smtpad_9", + "pcb_port_9", + "pcb_smtpad_18", + "pcb_port_18" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 0.54, + "center": { "x": -2.1500000000000004, "y": 4.16 }, + "height": 0.64, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_10", + "connectivity_net8", + "source_trace_3", + "source_port_10", + "source_port_0", + "pcb_smtpad_0", + "pcb_port_0", + "pcb_smtpad_10", + "pcb_port_10" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 0.54, + "center": { "x": -1.1300000000000006, "y": 4.16 }, + "height": 0.64, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_11", + "connectivity_net26", + "source_trace_10", + "source_port_17", + "source_trace_6", + "source_port_13", + "source_trace_4", + "source_port_11", + "source_trace_2", + "source_port_3", + "source_trace_0", + "source_port_1", + "source_net_0", + "pcb_smtpad_1", + "pcb_port_1", + "pcb_smtpad_3", + "pcb_port_3", + "pcb_smtpad_11", + "pcb_port_11", + "pcb_smtpad_13", + "pcb_port_13", + "pcb_smtpad_17", + "pcb_port_17" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 0.64, + "center": { "x": 3.97, "y": -3.2861261293105146 }, + "height": 0.54, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_12", + "connectivity_net13", + "source_trace_5", + "source_port_12", + "source_port_5", + "pcb_smtpad_5", + "pcb_port_5", + "pcb_smtpad_12", + "pcb_port_12" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 0.64, + "center": { "x": 3.97, "y": -4.306126129310514 }, + "height": 0.54, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_13", + "connectivity_net26", + "source_trace_10", + "source_port_17", + "source_trace_6", + "source_port_13", + "source_trace_4", + "source_port_11", + "source_trace_2", + "source_port_3", + "source_trace_0", + "source_port_1", + "source_net_0", + "pcb_smtpad_1", + "pcb_port_1", + "pcb_smtpad_3", + "pcb_port_3", + "pcb_smtpad_11", + "pcb_port_11", + "pcb_smtpad_13", + "pcb_port_13", + "pcb_smtpad_17", + "pcb_port_17" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 4.15, "y": 0.8238738706894861 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_14", + "connectivity_net18", + "source_trace_7", + "source_port_14", + "source_port_7", + "pcb_smtpad_7", + "pcb_port_7", + "pcb_smtpad_14", + "pcb_port_14" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 4.15, "y": -0.4461261293105139 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_15", + "connectivity_net21", + "source_trace_8", + "source_port_15", + "source_port_6", + "pcb_smtpad_6", + "pcb_port_6", + "pcb_smtpad_15", + "pcb_port_15" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 4.15, "y": -1.716126129310514 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_16", + "connectivity_net24", + "source_trace_9", + "source_port_16", + "source_trace_1", + "source_port_2", + "source_net_1", + "pcb_smtpad_2", + "pcb_port_2", + "pcb_smtpad_16", + "pcb_port_16" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 8.45, "y": -1.716126129310514 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_17", + "connectivity_net26", + "source_trace_10", + "source_port_17", + "source_trace_6", + "source_port_13", + "source_trace_4", + "source_port_11", + "source_trace_2", + "source_port_3", + "source_trace_0", + "source_port_1", + "source_net_0", + "pcb_smtpad_1", + "pcb_port_1", + "pcb_smtpad_3", + "pcb_port_3", + "pcb_smtpad_11", + "pcb_port_11", + "pcb_smtpad_13", + "pcb_port_13", + "pcb_smtpad_17", + "pcb_port_17" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 8.45, "y": -0.4461261293105139 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_18", + "connectivity_net28", + "source_trace_11", + "source_port_18", + "source_port_9", + "pcb_smtpad_9", + "pcb_port_9", + "pcb_smtpad_18", + "pcb_port_18" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 1, + "center": { "x": 8.45, "y": 0.8238738706894861 }, + "height": 0.6, + "layers": ["top"], + "connectedTo": [ + "pcb_smtpad_19", + "connectivity_net31", + "source_trace_12", + "source_port_19", + "source_port_8", + "pcb_smtpad_8", + "pcb_port_8", + "pcb_smtpad_19", + "pcb_port_19" + ], + "zLayers": [0] + }, + { + "type": "rect", + "width": 20, + "center": { "x": 0, "y": 0 }, + "height": 10, + "layers": ["bottom"], + "connectedTo": [ + "source_net_0", + "unnamedsubcircuit760_connectivity_net0", + "connectivity_net26", + "source_trace_10", + "source_port_17", + "source_trace_6", + "source_port_13", + "source_trace_4", + "source_port_11", + "source_trace_2", + "source_port_3", + "source_trace_0", + "source_port_1", + "source_net_0", + "pcb_smtpad_1", + "pcb_port_1", + "pcb_smtpad_3", + "pcb_port_3", + "pcb_smtpad_11", + "pcb_port_11", + "pcb_smtpad_13", + "pcb_port_13", + "pcb_smtpad_17", + "pcb_port_17" + ], + "isCopperPour": true, + "zLayers": [3] + }, + { + "type": "rect", + "width": 20, + "center": { "x": 0, "y": 0 }, + "height": 10, + "layers": ["inner2"], + "connectedTo": [ + "source_net_1", + "unnamedsubcircuit760_connectivity_net1", + "connectivity_net24", + "source_trace_9", + "source_port_16", + "source_trace_1", + "source_port_2", + "source_net_1", + "pcb_smtpad_2", + "pcb_port_2", + "pcb_smtpad_16", + "pcb_port_16" + ], + "isCopperPour": true, + "zLayers": [2] + }, + { + "obstacleId": "escape-via-obstacle:escape-via:source_trace_9:pcb_port_16:inner2:0", + "type": "rect", + "layers": ["top", "inner1", "inner2"], + "zLayers": [0, 1, 2], + "center": { "x": 3.3500000000000005, "y": -1.716126129310514 }, + "width": 0.3, + "height": 0.3, + "connectedTo": ["source_trace_9"] + }, + { + "obstacleId": "escape-via-obstacle:escape-via:source_net_1:pcb_port_2:inner2:2", + "type": "rect", + "layers": ["top", "inner1", "inner2"], + "zLayers": [0, 1, 2], + "center": { "x": -1.3499999999999999, "y": 0 }, + "width": 0.3, + "height": 0.3, + "connectedTo": ["source_net_1"] + }, + { + "obstacleId": "escape-via-obstacle:escape-via:source_net_0:pcb_port_11:bottom:3", + "type": "rect", + "layers": ["top", "inner1", "inner2", "bottom"], + "zLayers": [0, 1, 2, 3], + "center": { "x": -0.5600000000000005, "y": 4.16 }, + "width": 0.3, + "height": 0.3, + "connectedTo": ["source_net_0"] + }, + { + "obstacleId": "escape-via-obstacle:escape-via:source_net_0:pcb_port_13:bottom:4", + "type": "rect", + "layers": ["top", "inner1", "inner2", "bottom"], + "zLayers": [0, 1, 2, 3], + "center": { "x": 3.3500000000000005, "y": -4.306126129310514 }, + "width": 0.3, + "height": 0.3, + "connectedTo": ["source_net_0"] + }, + { + "obstacleId": "escape-via-obstacle:escape-via:source_net_0:pcb_port_1:bottom:6", + "type": "rect", + "layers": ["top", "inner1", "inner2", "bottom"], + "zLayers": [0, 1, 2, 3], + "center": { "x": -1.3499999999999999, "y": 1.27 }, + "width": 0.3, + "height": 0.3, + "connectedTo": ["source_net_0"] + }, + { + "obstacleId": "escape-via-obstacle:escape-via:source_net_0:pcb_port_3:bottom:8", + "type": "rect", + "layers": ["top", "inner1", "inner2", "bottom"], + "zLayers": [0, 1, 2, 3], + "center": { "x": -1.3499999999999999, "y": -1.27 }, + "width": 0.3, + "height": 0.3, + "connectedTo": ["source_net_0"] + }, + { + "obstacleId": "escape-via-obstacle:escape-via:source_net_0:pcb_port_17:bottom:9", + "type": "rect", + "layers": ["top", "inner1", "inner2", "bottom"], + "zLayers": [0, 1, 2, 3], + "center": { "x": 7.6499999999999995, "y": -1.716126129310514 }, + "width": 0.3, + "height": 0.3, + "connectedTo": ["source_net_0"] + } + ], + "layerCount": 4, + "connections": [ + { + "pointsToConnect": [ + { + "x": -1.1300000000000006, + "y": 4.16, + "layer": "top", + "pointId": "pcb_port_11", + "pcb_port_id": "pcb_port_11" + }, + { + "x": -0.5600000000000005, + "y": 4.16, + "layer": "top", + "pointId": "escape-via:source_net_0:pcb_port_11:bottom:3", + "terminalVia": { "toLayer": "bottom", "viaDiameter": 0.3 } + } + ], + "name": "source_net_0_mst0", + "rootConnectionName": "source_net_0" + }, + { + "pointsToConnect": [ + { + "x": 3.3500000000000005, + "y": -4.306126129310514, + "layer": "top", + "pointId": "escape-via:source_net_0:pcb_port_13:bottom:4", + "terminalVia": { "toLayer": "bottom", "viaDiameter": 0.3 } + }, + { + "x": 3.97, + "y": -4.306126129310514, + "layer": "top", + "pointId": "pcb_port_13", + "pcb_port_id": "pcb_port_13" + } + ], + "name": "source_net_0_mst1", + "rootConnectionName": "source_net_0" + }, + { + "pointsToConnect": [ + { + "x": 7.6499999999999995, + "y": -1.716126129310514, + "layer": "top", + "pointId": "escape-via:source_net_0:pcb_port_17:bottom:9", + "terminalVia": { "toLayer": "bottom", "viaDiameter": 0.3 } + }, + { + "x": 8.45, + "y": -1.716126129310514, + "layer": "top", + "pointId": "pcb_port_17", + "pcb_port_id": "pcb_port_17" + } + ], + "name": "source_net_0_mst2", + "rootConnectionName": "source_net_0" + }, + { + "pointsToConnect": [ + { + "x": -2.15, + "y": 1.27, + "layer": "top", + "pointId": "pcb_port_1", + "pcb_port_id": "pcb_port_1" + }, + { + "x": -1.3499999999999999, + "y": 1.27, + "layer": "top", + "pointId": "escape-via:source_net_0:pcb_port_1:bottom:6", + "terminalVia": { "toLayer": "bottom", "viaDiameter": 0.3 } + } + ], + "name": "source_net_0_mst3", + "rootConnectionName": "source_net_0" + }, + { + "pointsToConnect": [ + { + "x": -2.15, + "y": -1.27, + "layer": "top", + "pointId": "pcb_port_3", + "pcb_port_id": "pcb_port_3" + }, + { + "x": -1.3499999999999999, + "y": -1.27, + "layer": "top", + "pointId": "escape-via:source_net_0:pcb_port_3:bottom:8", + "terminalVia": { "toLayer": "bottom", "viaDiameter": 0.3 } + } + ], + "name": "source_net_0_mst4", + "rootConnectionName": "source_net_0" + }, + { + "name": "source_trace_12", + "pointsToConnect": [ + { + "x": 8.45, + "y": 0.8238738706894861, + "layer": "top", + "pointId": "pcb_port_19", + "pcb_port_id": "pcb_port_19" + }, + { + "x": 2.15, + "y": 1.27, + "layer": "top", + "pointId": "pcb_port_8", + "pcb_port_id": "pcb_port_8" + } + ], + "source_trace_id": "source_trace_12", + "rootConnectionName": "source_trace_12" + }, + { + "name": "source_trace_11", + "pointsToConnect": [ + { + "x": 8.45, + "y": -0.4461261293105139, + "layer": "top", + "pointId": "pcb_port_18", + "pcb_port_id": "pcb_port_18" + }, + { + "x": 2.15, + "y": 2.54, + "layer": "top", + "pointId": "pcb_port_9", + "pcb_port_id": "pcb_port_9" + } + ], + "source_trace_id": "source_trace_11", + "rootConnectionName": "source_trace_11" + }, + { + "pointsToConnect": [ + { + "x": 3.3500000000000005, + "y": -1.716126129310514, + "layer": "top", + "pointId": "escape-via:source_trace_9:pcb_port_16:inner2:0", + "terminalVia": { "toLayer": "inner2", "viaDiameter": 0.3 } + }, + { + "x": 4.15, + "y": -1.716126129310514, + "layer": "top", + "pointId": "pcb_port_16", + "pcb_port_id": "pcb_port_16" + } + ], + "name": "source_trace_9__source_net_1_mst0", + "rootConnectionName": "source_trace_9__source_net_1", + "mergedConnectionNames": { + "$ref": "$.simpleRouteJson.connections[8].mergedConnectionNames" + } + }, + { + "pointsToConnect": [ + { + "x": -2.15, + "y": 0, + "layer": "top", + "pointId": "pcb_port_2", + "pcb_port_id": "pcb_port_2" + }, + { + "x": -1.3499999999999999, + "y": 0, + "layer": "top", + "pointId": "escape-via:source_net_1:pcb_port_2:inner2:2", + "terminalVia": { "toLayer": "inner2", "viaDiameter": 0.3 } + } + ], + "name": "source_trace_9__source_net_1_mst1", + "rootConnectionName": "source_trace_9__source_net_1", + "mergedConnectionNames": ["source_trace_9", "source_net_1"] + }, + { + "name": "source_trace_8", + "pointsToConnect": [ + { + "x": 4.15, + "y": -0.4461261293105139, + "layer": "top", + "pointId": "pcb_port_15", + "pcb_port_id": "pcb_port_15" + }, + { + "x": 2.15, + "y": -1.27, + "layer": "top", + "pointId": "pcb_port_6", + "pcb_port_id": "pcb_port_6" + } + ], + "source_trace_id": "source_trace_8", + "rootConnectionName": "source_trace_8" + }, + { + "name": "source_trace_7", + "pointsToConnect": [ + { + "x": 4.15, + "y": 0.8238738706894861, + "layer": "top", + "pointId": "pcb_port_14", + "pcb_port_id": "pcb_port_14" + }, + { + "x": 2.15, + "y": 0, + "layer": "top", + "pointId": "pcb_port_7", + "pcb_port_id": "pcb_port_7" + } + ], + "source_trace_id": "source_trace_7", + "rootConnectionName": "source_trace_7" + }, + { + "name": "source_trace_5", + "pointsToConnect": [ + { + "x": 3.97, + "y": -3.2861261293105146, + "layer": "top", + "pointId": "pcb_port_12", + "pcb_port_id": "pcb_port_12" + }, + { + "x": 2.15, + "y": -2.54, + "layer": "top", + "pointId": "pcb_port_5", + "pcb_port_id": "pcb_port_5" + } + ], + "source_trace_id": "source_trace_5", + "rootConnectionName": "source_trace_5" + }, + { + "name": "source_trace_3", + "pointsToConnect": [ + { + "x": -2.1500000000000004, + "y": 4.16, + "layer": "top", + "pointId": "pcb_port_10", + "pcb_port_id": "pcb_port_10" + }, + { + "x": -2.15, + "y": 2.54, + "layer": "top", + "pointId": "pcb_port_0", + "pcb_port_id": "pcb_port_0" + } + ], + "source_trace_id": "source_trace_3", + "rootConnectionName": "source_trace_3" + } + ], + "minTraceWidth": 0.15 + } + } +] diff --git a/tests/solver/pour-via-escape-06/pour-via-escape-06.test.ts b/tests/solver/pour-via-escape-06/pour-via-escape-06.test.ts new file mode 100644 index 0000000..859cf14 --- /dev/null +++ b/tests/solver/pour-via-escape-06/pour-via-escape-06.test.ts @@ -0,0 +1,94 @@ +import { expect, test } from "bun:test" +import srj_json from "./pour-via-escape-06.json" +import { + getBounds, + getSvgFromGraphicsObject, + mergeGraphics, + stackGraphicsVertically, + type GraphicsObject, + type Rect, +} from "graphics-debug" +import { RectDiffPipeline } from "lib/RectDiffPipeline" +import { makeCapacityMeshNodeWithLayerInfo } from "tests/fixtures/makeCapacityMeshNodeWithLayerInfo" +import { makeSimpleRouteOutlineGraphics } from "tests/fixtures/makeSimpleRouteOutlineGraphics" + +const srj_root = Array.isArray(srj_json) ? srj_json[0] : srj_json +const srj = srj_root.simple_route_json ?? srj_root.simpleRouteJson ?? srj_root + +test("pour-via-escape-06", async () => { + const solver = new RectDiffPipeline({ + simpleRouteJson: srj, + }) + + const outline = makeSimpleRouteOutlineGraphics(srj) + + solver.solve() + + const { meshNodes } = solver.getOutput() + const rectsByCombo = makeCapacityMeshNodeWithLayerInfo(meshNodes) + const allGraphicsObjects: GraphicsObject[] = [] + + for (const z of Array.from({ length: srj.layerCount }, (_, index) => index)) { + const layerRects: Rect[] = [] + + for (const [key, rects] of rectsByCombo) { + const layers = key + .split(",") + .map((value) => Number.parseInt(value, 10)) + .filter((value) => !Number.isNaN(value)) + + if (layers.includes(z)) { + layerRects.push(...rects) + } + } + + let labelY = 0 + + if (layerRects.length > 0) { + let maxY = -Infinity + + for (const rect of layerRects) { + const top = rect.center.y + rect.height * (2 / 3) + + if (top > maxY) maxY = top + } + + labelY = maxY + } + + const graphics: GraphicsObject = { + title: `RectDiffPipeline - z${z}`, + texts: [ + { + anchorSide: "top_right", + text: `Layer z=${z}`, + x: 0, + y: labelY, + fontSize: 0.5, + }, + ], + coordinateSystem: "cartesian", + rects: layerRects, + points: [], + lines: [], + } + + allGraphicsObjects.push(mergeGraphics(graphics, outline)) + } + + const stackedGraphics = stackGraphicsVertically(allGraphicsObjects) + const bounds = getBounds(stackedGraphics) + const boundsWidth = Math.max(1, bounds.maxX - bounds.minX) + const boundsHeight = Math.max(1, bounds.maxY - bounds.minY) + const svgWidth = 640 + const svgHeight = Math.max( + svgWidth, + Math.ceil((boundsHeight / boundsWidth) * svgWidth), + ) + + const svg = getSvgFromGraphicsObject(stackedGraphics, { + svgWidth, + svgHeight, + }) + await expect(svg).toMatchSvgSnapshot(import.meta.path) +})