From 9f743e045fbf921a2686e67f725143f319fa2258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?0hm=E2=98=98=EF=B8=8F?= <109351887+0hmX@users.noreply.github.com> Date: Thu, 25 Dec 2025 02:07:01 +0530 Subject: [PATCH] Ensure board void rects in obstacle index --- .../RectDiffExpansionSolver.ts | 5 +++ .../RectDiffSeedingSolver.ts | 5 +++ .../ensureBoardVoidRectsInObstacleIndex.ts | 37 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 lib/utils/ensureBoardVoidRectsInObstacleIndex.ts diff --git a/lib/solvers/RectDiffExpansionSolver/RectDiffExpansionSolver.ts b/lib/solvers/RectDiffExpansionSolver/RectDiffExpansionSolver.ts index a7108d1..4793324 100644 --- a/lib/solvers/RectDiffExpansionSolver/RectDiffExpansionSolver.ts +++ b/lib/solvers/RectDiffExpansionSolver/RectDiffExpansionSolver.ts @@ -16,6 +16,7 @@ import { import RBush from "rbush" import { rectToTree } from "../../utils/rectToTree" import { sameTreeRect } from "../../utils/sameTreeRect" +import { ensureBoardVoidRectsInObstacleIndex } from "lib/utils/ensureBoardVoidRectsInObstacleIndex" export type RectDiffExpansionSolverSnapshot = { srj: SimpleRouteJson @@ -108,6 +109,10 @@ export class RectDiffExpansionSolver extends BaseSolver { }) } } + this.input.obstacleIndexByLayer = ensureBoardVoidRectsInObstacleIndex( + this.boardVoidRects, + this.input.obstacleIndexByLayer, + ) this.placedIndexByLayer = Array.from( { length: this.layerCount }, diff --git a/lib/solvers/RectDiffSeedingSolver/RectDiffSeedingSolver.ts b/lib/solvers/RectDiffSeedingSolver/RectDiffSeedingSolver.ts index 129e459..0f11712 100644 --- a/lib/solvers/RectDiffSeedingSolver/RectDiffSeedingSolver.ts +++ b/lib/solvers/RectDiffSeedingSolver/RectDiffSeedingSolver.ts @@ -20,6 +20,7 @@ import { isFullyOccupiedAtPoint } from "lib/utils/isFullyOccupiedAtPoint" import { resizeSoftOverlaps } from "../../utils/resizeSoftOverlaps" import RBush from "rbush" import type { RTreeRect } from "lib/types/capacity-mesh-types" +import { ensureBoardVoidRectsInObstacleIndex } from "lib/utils/ensureBoardVoidRectsInObstacleIndex" export type RectDiffSeedingSolverInput = { simpleRouteJson: SimpleRouteJson @@ -110,6 +111,10 @@ export class RectDiffSeedingSolver extends BaseSolver { this.bounds = bounds this.options = options this.boardVoidRects = this.input.boardVoidRects + this.input.obstacleIndexByLayer = ensureBoardVoidRectsInObstacleIndex( + this.boardVoidRects, + this.input.obstacleIndexByLayer, + ) this.gridIndex = 0 this.candidates = [] this.placed = [] diff --git a/lib/utils/ensureBoardVoidRectsInObstacleIndex.ts b/lib/utils/ensureBoardVoidRectsInObstacleIndex.ts new file mode 100644 index 0000000..9852d67 --- /dev/null +++ b/lib/utils/ensureBoardVoidRectsInObstacleIndex.ts @@ -0,0 +1,37 @@ +import RBush from "rbush" +import type { XYRect } from "lib/rectdiff-types" +import type { RTreeRect } from "lib/types/capacity-mesh-types" +import { rectToTree } from "./rectToTree" +import { sameTreeRect } from "./sameTreeRect" + +export const ensureBoardVoidRectsInObstacleIndex = ( + boardVoidRects: XYRect[] | undefined, + obstacleIndexByLayer: Array>, +): Array> => { + if (!boardVoidRects?.length) return obstacleIndexByLayer + + for (let z = 0; z < obstacleIndexByLayer.length; z++) { + if (!obstacleIndexByLayer[z]) { + obstacleIndexByLayer[z] = new RBush() + } + const tree = obstacleIndexByLayer[z]! + const existing = tree.all() + const seen = new Set() + for (const rect of existing) { + seen.add(`${rect.minX}:${rect.minY}:${rect.maxX}:${rect.maxY}`) + } + + for (const rect of boardVoidRects) { + const treeRect = rectToTree(rect) + const key = `${treeRect.minX}:${treeRect.minY}:${treeRect.maxX}:${treeRect.maxY}` + if (seen.has(key)) continue + if (!existing.some((item) => sameTreeRect(item, treeRect))) { + tree.insert(treeRect) + existing.push(treeRect) + seen.add(key) + } + } + } + + return obstacleIndexByLayer +}