diff --git a/lib/ConvertContext.ts b/lib/ConvertContext.ts index fccc5bf..236b0b6 100644 --- a/lib/ConvertContext.ts +++ b/lib/ConvertContext.ts @@ -16,5 +16,8 @@ export interface ConvertContext { netGeoms: Map> + copperLayerPolygons: Polygon[] + boardCutPolygons: Polygon[] + origin: { x: number; y: number } } diff --git a/lib/element-handlers/addPcbBoard/index.ts b/lib/element-handlers/addPcbBoard/index.ts index 6e58ccb..4c56f77 100644 --- a/lib/element-handlers/addPcbBoard/index.ts +++ b/lib/element-handlers/addPcbBoard/index.ts @@ -1,11 +1,9 @@ import { Polygon, point } from "@flatten-js/core" import type { PcbBoard } from "circuit-json" -import { ShapePath } from "lbrnts" import type { ConvertContext } from "../../ConvertContext" -import { polygonToShapePathData } from "../../polygon-to-shape-path" export const addPcbBoard = (board: PcbBoard, ctx: ConvertContext) => { - const { origin, project, throughBoardCutSetting } = ctx + const { origin, boardCutPolygons } = ctx let polygon: Polygon | null = null @@ -37,14 +35,5 @@ export const addPcbBoard = (board: PcbBoard, ctx: ConvertContext) => { if (!polygon) return - const { verts, prims } = polygonToShapePathData(polygon) - - project.children.push( - new ShapePath({ - cutIndex: throughBoardCutSetting.index, - verts, - prims, - isClosed: true, - }), - ) + boardCutPolygons.push(polygon) } diff --git a/lib/index.ts b/lib/index.ts index 2e59852..023d2c2 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -61,6 +61,8 @@ export const convertCircuitJsonToLbrn = ( throughBoardCutSetting, connMap, netGeoms: new Map(), + copperLayerPolygons: [], + boardCutPolygons: [], origin, } @@ -111,7 +113,8 @@ export const convertCircuitJsonToLbrn = ( // } // } - // Create a union of all the net geoms, and add to project + // Phase 1: Construct flattenjs polygons for each cutting layer + // Create a union of all the net geoms and collect polygons for the copper layer for (const net of Object.keys(connMap.netMap)) { const netGeoms = ctx.netGeoms.get(net)! @@ -137,18 +140,47 @@ export const convertCircuitJsonToLbrn = ( // } for (const island of union.splitToIslands()) { - // Convert the polygon to verts and prims - const { verts, prims } = polygonToShapePathData(island) - - project.children.push( - new ShapePath({ - cutIndex: copperCutSetting.index, - verts, - prims, - isClosed: false, - }), - ) + ctx.copperLayerPolygons.push(island) } } + // Phase 2: Construct a single cut path for each cutting layer + + if (ctx.copperLayerPolygons.length > 0) { + const [firstCopper, ...restCopper] = ctx.copperLayerPolygons + let copperUnion: Polygon = firstCopper! + for (const poly of restCopper) { + copperUnion = BooleanOperations.unify(copperUnion, poly) + } + + const { verts, prims } = polygonToShapePathData(copperUnion) + + project.children.push( + new ShapePath({ + cutIndex: copperCutSetting.index, + verts, + prims, + isClosed: false, + }), + ) + } + + if (ctx.boardCutPolygons.length > 0) { + const [firstBoard, ...restBoards] = ctx.boardCutPolygons + let boardUnion: Polygon = firstBoard! + for (const poly of restBoards) { + boardUnion = BooleanOperations.unify(boardUnion, poly) + } + + const { verts, prims } = polygonToShapePathData(boardUnion) + + project.children.push( + new ShapePath({ + cutIndex: throughBoardCutSetting.index, + verts, + prims, + isClosed: true, + }), + ) + } return project } diff --git a/tests/examples/__snapshots__/lga-interconnect.snap.svg b/tests/examples/__snapshots__/lga-interconnect.snap.svg index ab6eae4..3ab1f17 100644 --- a/tests/examples/__snapshots__/lga-interconnect.snap.svg +++ b/tests/examples/__snapshots__/lga-interconnect.snap.svg @@ -3,6 +3,6 @@ C1X18X9C18X17X8C17X16X7C16X15X6C15X14X5X1X10C3NET1C14NET1C6C8C9C2C5C12C4C7X13X4X2X11C11NET1C10C13X12X3 - + \ No newline at end of file