circuit-json-to-lbrn 0.0.44 → 0.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2577,7 +2577,8 @@ var createCopperCutFillForLayer = async ({
2577
2577
  bottomCutNetGeoms,
2578
2578
  topCopperCutFillCutSetting,
2579
2579
  bottomCopperCutFillCutSetting,
2580
- copperCutFillMargin
2580
+ copperCutFillMargin,
2581
+ boardOutlineContour
2581
2582
  } = ctx;
2582
2583
  const cutSetting = layer === "top" ? topCopperCutFillCutSetting : bottomCopperCutFillCutSetting;
2583
2584
  if (!cutSetting) {
@@ -2615,7 +2616,14 @@ var createCopperCutFillForLayer = async ({
2615
2616
  32
2616
2617
  // circularSegments for round corners
2617
2618
  );
2618
- const cutFillArea = outerBoundary.subtract(copperInside);
2619
+ let cutFillArea = outerBoundary.subtract(copperInside);
2620
+ if (boardOutlineContour && boardOutlineContour.length >= 3) {
2621
+ const boardOutline = new CrossSection([boardOutlineContour], "Positive");
2622
+ const clippedArea = cutFillArea.intersect(boardOutline);
2623
+ cutFillArea.delete();
2624
+ cutFillArea = clippedArea;
2625
+ boardOutline.delete();
2626
+ }
2619
2627
  const simplifiedArea = cutFillArea.simplify(1e-3);
2620
2628
  const resultContours = simplifiedArea.toPolygons();
2621
2629
  if (resultContours.length === 0) {
@@ -2835,6 +2843,28 @@ var convertCircuitJsonToLbrn = async (circuitJson, options = {}) => {
2835
2843
  ctx.topScanNetGeoms.set(net, []);
2836
2844
  ctx.bottomScanNetGeoms.set(net, []);
2837
2845
  }
2846
+ for (const board of db.pcb_board.list()) {
2847
+ if (board.outline?.length) {
2848
+ ctx.boardOutlineContour = board.outline.map((outlinePoint) => [
2849
+ outlinePoint.x + origin.x,
2850
+ outlinePoint.y + origin.y
2851
+ ]);
2852
+ } else if (typeof board.width === "number" && typeof board.height === "number" && board.center) {
2853
+ const halfWidth = board.width / 2;
2854
+ const halfHeight = board.height / 2;
2855
+ const minX = board.center.x - halfWidth + origin.x;
2856
+ const minY = board.center.y - halfHeight + origin.y;
2857
+ const maxX = board.center.x + halfWidth + origin.x;
2858
+ const maxY = board.center.y + halfHeight + origin.y;
2859
+ ctx.boardOutlineContour = [
2860
+ [minX, minY],
2861
+ [maxX, minY],
2862
+ [maxX, maxY],
2863
+ [minX, maxY]
2864
+ ];
2865
+ }
2866
+ break;
2867
+ }
2838
2868
  for (const smtpad of db.pcb_smtpad.list()) {
2839
2869
  addSmtPad(smtpad, ctx);
2840
2870
  }
@@ -3,6 +3,8 @@ import type { CutSetting, LightBurnProject } from "lbrnts"
3
3
  import type { Box, Polygon } from "@flatten-js/core"
4
4
  import type { ConnectivityMap } from "circuit-json-to-connectivity-map"
5
5
 
6
+ type Contour = Array<[number, number]>
7
+
6
8
  export type ConnectivityMapKey = string
7
9
 
8
10
  export interface ConvertContext {
@@ -58,4 +60,7 @@ export interface ConvertContext {
58
60
  // Key is "x,y" rounded to 6 decimal places
59
61
  topTraceEndpoints: Set<string>
60
62
  bottomTraceEndpoints: Set<string>
63
+
64
+ // Board outline as a contour for clipping copper cut fill
65
+ boardOutlineContour?: Contour
61
66
  }
@@ -100,6 +100,7 @@ export const createCopperCutFillForLayer = async ({
100
100
  topCopperCutFillCutSetting,
101
101
  bottomCopperCutFillCutSetting,
102
102
  copperCutFillMargin,
103
+ boardOutlineContour,
103
104
  } = ctx
104
105
 
105
106
  // Get the appropriate cut setting for this layer
@@ -157,7 +158,16 @@ export const createCopperCutFillForLayer = async ({
157
158
 
158
159
  // Subtract the inside (original copper) from the outer boundary (expanded copper)
159
160
  // This gives us the ring/band area to laser cut
160
- const cutFillArea = outerBoundary.subtract(copperInside)
161
+ let cutFillArea = outerBoundary.subtract(copperInside)
162
+
163
+ // Clip to board outline if available
164
+ if (boardOutlineContour && boardOutlineContour.length >= 3) {
165
+ const boardOutline = new CrossSection([boardOutlineContour], "Positive")
166
+ const clippedArea = cutFillArea.intersect(boardOutline)
167
+ cutFillArea.delete()
168
+ cutFillArea = clippedArea
169
+ boardOutline.delete()
170
+ }
161
171
 
162
172
  // Simplify to clean up any spurious tiny segments
163
173
  const simplifiedArea = cutFillArea.simplify(0.001)
package/lib/index.ts CHANGED
@@ -269,6 +269,34 @@ export const convertCircuitJsonToLbrn = async (
269
269
  ctx.bottomScanNetGeoms.set(net, [])
270
270
  }
271
271
 
272
+ // Extract board outline for clipping copper cut fill
273
+ for (const board of db.pcb_board.list()) {
274
+ if (board.outline?.length) {
275
+ ctx.boardOutlineContour = board.outline.map((outlinePoint) => [
276
+ outlinePoint.x + origin.x,
277
+ outlinePoint.y + origin.y,
278
+ ])
279
+ } else if (
280
+ typeof board.width === "number" &&
281
+ typeof board.height === "number" &&
282
+ board.center
283
+ ) {
284
+ const halfWidth = board.width / 2
285
+ const halfHeight = board.height / 2
286
+ const minX = board.center.x - halfWidth + origin.x
287
+ const minY = board.center.y - halfHeight + origin.y
288
+ const maxX = board.center.x + halfWidth + origin.x
289
+ const maxY = board.center.y + halfHeight + origin.y
290
+ ctx.boardOutlineContour = [
291
+ [minX, minY],
292
+ [maxX, minY],
293
+ [maxX, maxY],
294
+ [minX, maxY],
295
+ ]
296
+ }
297
+ break // Only use the first board
298
+ }
299
+
272
300
  // Process all PCB elements
273
301
  for (const smtpad of db.pcb_smtpad.list()) {
274
302
  addSmtPad(smtpad, ctx)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "circuit-json-to-lbrn",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.44",
4
+ "version": "0.0.45",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "bun run site/index.html",