circuit-json-to-lbrn 0.0.39 → 0.0.41

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.
Files changed (27) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +388 -374
  3. package/lib/ConvertContext.ts +3 -0
  4. package/lib/element-handlers/addPcbVia/index.ts +11 -2
  5. package/lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts +9 -3
  6. package/lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts +33 -30
  7. package/lib/element-handlers/addPlatedHole/addHoleWithPolygonPad.ts +13 -22
  8. package/lib/element-handlers/addPlatedHole/addOvalPlatedHole.ts +20 -4
  9. package/lib/element-handlers/addPlatedHole/addPillHoleWithRectPad.ts +32 -30
  10. package/lib/element-handlers/addPlatedHole/addPillPlatedHole.ts +21 -8
  11. package/lib/element-handlers/addPlatedHole/addRotatedPillHoleWithRectPad.ts +32 -30
  12. package/lib/element-handlers/addSmtPad/addCircleSmtPad.ts +33 -38
  13. package/lib/element-handlers/addSmtPad/addPillSmtPad.ts +27 -37
  14. package/lib/element-handlers/addSmtPad/addPolygonSmtPad.ts +9 -29
  15. package/lib/element-handlers/addSmtPad/addRectSmtPad.ts +29 -51
  16. package/lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts +27 -37
  17. package/lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts +27 -37
  18. package/lib/helpers/addCopperGeometryToNetOrProject.ts +48 -0
  19. package/lib/index.ts +3 -0
  20. package/package.json +1 -1
  21. package/tests/basics/soldermask-margin/__snapshots__/negative-soldermask-margin.snap.svg +1 -1
  22. package/tests/basics/soldermask-margin/__snapshots__/percent-soldermask-margin.snap.svg +8 -0
  23. package/tests/basics/soldermask-margin/percent-soldermask-margin.test.ts +90 -0
  24. package/tests/examples/example02/__snapshots__/example02.snap.svg +1 -1
  25. package/tests/examples/example04/1206x4_3216metric.json +2973 -0
  26. package/tests/examples/example04/__snapshots__/example04.snap.svg +1 -0
  27. package/tests/examples/example04/example04.test.ts +32 -0
package/dist/index.js CHANGED
@@ -62,6 +62,7 @@ var addCirclePlatedHole = (platedHole, ctx) => {
62
62
  includeSoldermask,
63
63
  connMap,
64
64
  globalCopperSoldermaskMarginAdjustment,
65
+ solderMaskMarginPercent,
65
66
  includeLayers
66
67
  } = ctx;
67
68
  const centerX = platedHole.x + origin.x;
@@ -107,7 +108,9 @@ var addCirclePlatedHole = (platedHole, ctx) => {
107
108
  }
108
109
  }
109
110
  if (platedHole.outer_diameter > 0 && includeSoldermask) {
110
- const smRadius = platedHole.outer_diameter / 2 + globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
111
+ const percentMargin = solderMaskMarginPercent / 100 * platedHole.outer_diameter;
112
+ const totalMargin = globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMargin;
113
+ const smRadius = Math.max(platedHole.outer_diameter / 2 + totalMargin, 0);
111
114
  const outer = createCirclePath({
112
115
  centerX,
113
116
  centerY,
@@ -189,6 +192,7 @@ var addOvalPlatedHole = (platedHole, ctx) => {
189
192
  includeCopper,
190
193
  includeSoldermask,
191
194
  globalCopperSoldermaskMarginAdjustment,
195
+ solderMaskMarginPercent,
192
196
  includeLayers
193
197
  } = ctx;
194
198
  if (platedHole.outer_width <= 0 || platedHole.outer_height <= 0) {
@@ -227,9 +231,18 @@ var addOvalPlatedHole = (platedHole, ctx) => {
227
231
  }
228
232
  }
229
233
  if (platedHole.outer_width > 0 && platedHole.outer_height > 0 && includeSoldermask) {
230
- const soldermaskMargin = globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
231
- const smWidth = platedHole.outer_width + 2 * soldermaskMargin;
232
- const smHeight = platedHole.outer_height + 2 * soldermaskMargin;
234
+ const percentMarginX = solderMaskMarginPercent / 100 * platedHole.outer_width;
235
+ const percentMarginY = solderMaskMarginPercent / 100 * platedHole.outer_height;
236
+ const totalMarginX = Math.max(
237
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginX,
238
+ -platedHole.outer_width / 2
239
+ );
240
+ const totalMarginY = Math.max(
241
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginY,
242
+ -platedHole.outer_height / 2
243
+ );
244
+ const smWidth = platedHole.outer_width + 2 * totalMarginX;
245
+ const smHeight = platedHole.outer_height + 2 * totalMarginY;
233
246
  const outer = createOvalPath({
234
247
  centerX,
235
248
  centerY,
@@ -266,7 +279,7 @@ var addOvalPlatedHole = (platedHole, ctx) => {
266
279
  };
267
280
 
268
281
  // lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts
269
- import { ShapePath as ShapePath3 } from "lbrnts";
282
+ import { ShapePath as ShapePath4 } from "lbrnts";
270
283
 
271
284
  // lib/helpers/roundedRectShape.ts
272
285
  var createRoundedRectPath = ({
@@ -357,18 +370,62 @@ var createRoundedRectPath = ({
357
370
  return { verts, prims };
358
371
  };
359
372
 
360
- // lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts
361
- var addCircularHoleWithRectPad = (platedHole, ctx) => {
373
+ // lib/helpers/addCopperGeometryToNetOrProject.ts
374
+ import { ShapePath as ShapePath3 } from "lbrnts";
375
+
376
+ // lib/helpers/pathToPolygon.ts
377
+ import { Polygon, point as point2 } from "@flatten-js/core";
378
+ var pathToPolygon = (verts) => {
379
+ const points = verts.map((v) => point2(v.x, v.y));
380
+ return new Polygon(points);
381
+ };
382
+
383
+ // lib/helpers/addCopperGeometryToNetOrProject.ts
384
+ var addCopperGeometryToNetOrProject = ({
385
+ geometryId,
386
+ path,
387
+ layer,
388
+ ctx
389
+ }) => {
362
390
  const {
363
391
  project,
392
+ connMap,
393
+ topCutNetGeoms,
394
+ bottomCutNetGeoms,
364
395
  topCopperCutSetting,
365
396
  bottomCopperCutSetting,
397
+ includeLayers
398
+ } = ctx;
399
+ if (!includeLayers.includes(layer)) return;
400
+ const netId = connMap.getNetConnectedToId(geometryId);
401
+ const cutSetting = layer === "top" ? topCopperCutSetting : bottomCopperCutSetting;
402
+ const netGeoms = layer === "top" ? topCutNetGeoms : bottomCutNetGeoms;
403
+ if (netId) {
404
+ const polygon = pathToPolygon(path.verts);
405
+ netGeoms.get(netId)?.push(polygon);
406
+ } else {
407
+ project.children.push(
408
+ new ShapePath3({
409
+ cutIndex: cutSetting.index,
410
+ verts: path.verts,
411
+ prims: path.prims,
412
+ isClosed: true
413
+ })
414
+ );
415
+ }
416
+ };
417
+
418
+ // lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts
419
+ var addCircularHoleWithRectPad = (platedHole, ctx) => {
420
+ const {
421
+ project,
366
422
  soldermaskCutSetting,
367
423
  throughBoardCutSetting,
368
424
  origin,
369
425
  includeCopper,
370
426
  includeSoldermask,
371
427
  globalCopperSoldermaskMarginAdjustment,
428
+ solderMaskMarginPercent,
372
429
  includeLayers
373
430
  } = ctx;
374
431
  const centerX = platedHole.x + origin.x;
@@ -385,30 +442,32 @@ var addCircularHoleWithRectPad = (platedHole, ctx) => {
385
442
  borderRadius
386
443
  });
387
444
  if (includeCopper) {
388
- if (includeLayers.includes("top")) {
389
- project.children.push(
390
- new ShapePath3({
391
- cutIndex: topCopperCutSetting.index,
392
- verts: padPath.verts,
393
- prims: padPath.prims,
394
- isClosed: true
395
- })
396
- );
397
- }
398
- if (includeLayers.includes("bottom")) {
399
- project.children.push(
400
- new ShapePath3({
401
- cutIndex: bottomCopperCutSetting.index,
402
- verts: padPath.verts,
403
- prims: padPath.prims,
404
- isClosed: true
405
- })
406
- );
407
- }
445
+ addCopperGeometryToNetOrProject({
446
+ geometryId: platedHole.pcb_plated_hole_id,
447
+ path: padPath,
448
+ layer: "top",
449
+ ctx
450
+ });
451
+ addCopperGeometryToNetOrProject({
452
+ geometryId: platedHole.pcb_plated_hole_id,
453
+ path: padPath,
454
+ layer: "bottom",
455
+ ctx
456
+ });
408
457
  }
409
458
  if (includeSoldermask) {
410
- const smPadWidth = padWidth + 2 * globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
411
- const smPadHeight = padHeight + 2 * globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
459
+ const percentMarginX = solderMaskMarginPercent / 100 * padWidth;
460
+ const percentMarginY = solderMaskMarginPercent / 100 * padHeight;
461
+ const totalMarginX = Math.max(
462
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginX,
463
+ -padWidth / 2
464
+ );
465
+ const totalMarginY = Math.max(
466
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginY,
467
+ -padHeight / 2
468
+ );
469
+ const smPadWidth = padWidth + 2 * totalMarginX;
470
+ const smPadHeight = padHeight + 2 * totalMarginY;
412
471
  const smPadPath = createRoundedRectPath({
413
472
  centerX,
414
473
  centerY,
@@ -417,7 +476,7 @@ var addCircularHoleWithRectPad = (platedHole, ctx) => {
417
476
  borderRadius
418
477
  });
419
478
  project.children.push(
420
- new ShapePath3({
479
+ new ShapePath4({
421
480
  cutIndex: soldermaskCutSetting.index,
422
481
  verts: smPadPath.verts,
423
482
  prims: smPadPath.prims,
@@ -435,7 +494,7 @@ var addCircularHoleWithRectPad = (platedHole, ctx) => {
435
494
  segments: 32
436
495
  });
437
496
  project.children.push(
438
- new ShapePath3({
497
+ new ShapePath4({
439
498
  cutIndex: throughBoardCutSetting.index,
440
499
  verts: holePath.verts,
441
500
  prims: holePath.prims,
@@ -446,7 +505,7 @@ var addCircularHoleWithRectPad = (platedHole, ctx) => {
446
505
  };
447
506
 
448
507
  // lib/element-handlers/addPlatedHole/addPillHoleWithRectPad.ts
449
- import { ShapePath as ShapePath4 } from "lbrnts";
508
+ import { ShapePath as ShapePath5 } from "lbrnts";
450
509
 
451
510
  // lib/helpers/pathPointUtils.ts
452
511
  var createPointAdder = ({
@@ -546,14 +605,13 @@ var createPillPath = ({
546
605
  var addPillHoleWithRectPad = (platedHole, ctx) => {
547
606
  const {
548
607
  project,
549
- topCopperCutSetting,
550
- bottomCopperCutSetting,
551
608
  soldermaskCutSetting,
552
609
  throughBoardCutSetting,
553
610
  origin,
554
611
  includeCopper,
555
612
  includeSoldermask,
556
613
  globalCopperSoldermaskMarginAdjustment,
614
+ solderMaskMarginPercent,
557
615
  includeLayers
558
616
  } = ctx;
559
617
  const centerX = platedHole.x + origin.x;
@@ -570,30 +628,32 @@ var addPillHoleWithRectPad = (platedHole, ctx) => {
570
628
  borderRadius
571
629
  });
572
630
  if (includeCopper) {
573
- if (includeLayers.includes("top")) {
574
- project.children.push(
575
- new ShapePath4({
576
- cutIndex: topCopperCutSetting.index,
577
- verts: padPath.verts,
578
- prims: padPath.prims,
579
- isClosed: true
580
- })
581
- );
582
- }
583
- if (includeLayers.includes("bottom")) {
584
- project.children.push(
585
- new ShapePath4({
586
- cutIndex: bottomCopperCutSetting.index,
587
- verts: padPath.verts,
588
- prims: padPath.prims,
589
- isClosed: true
590
- })
591
- );
592
- }
631
+ addCopperGeometryToNetOrProject({
632
+ geometryId: platedHole.pcb_plated_hole_id,
633
+ path: padPath,
634
+ layer: "top",
635
+ ctx
636
+ });
637
+ addCopperGeometryToNetOrProject({
638
+ geometryId: platedHole.pcb_plated_hole_id,
639
+ path: padPath,
640
+ layer: "bottom",
641
+ ctx
642
+ });
593
643
  }
594
644
  if (includeSoldermask) {
595
- const smPadWidth = padWidth + 2 * globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
596
- const smPadHeight = padHeight + 2 * globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
645
+ const percentMarginX = solderMaskMarginPercent / 100 * padWidth;
646
+ const percentMarginY = solderMaskMarginPercent / 100 * padHeight;
647
+ const totalMarginX = Math.max(
648
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginX,
649
+ -padWidth / 2
650
+ );
651
+ const totalMarginY = Math.max(
652
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginY,
653
+ -padHeight / 2
654
+ );
655
+ const smPadWidth = padWidth + 2 * totalMarginX;
656
+ const smPadHeight = padHeight + 2 * totalMarginY;
597
657
  const smPadPath = createRoundedRectPath({
598
658
  centerX,
599
659
  centerY,
@@ -602,7 +662,7 @@ var addPillHoleWithRectPad = (platedHole, ctx) => {
602
662
  borderRadius
603
663
  });
604
664
  project.children.push(
605
- new ShapePath4({
665
+ new ShapePath5({
606
666
  cutIndex: soldermaskCutSetting.index,
607
667
  verts: smPadPath.verts,
608
668
  prims: smPadPath.prims,
@@ -623,7 +683,7 @@ var addPillHoleWithRectPad = (platedHole, ctx) => {
623
683
  height: holeHeight
624
684
  });
625
685
  project.children.push(
626
- new ShapePath4({
686
+ new ShapePath5({
627
687
  cutIndex: throughBoardCutSetting.index,
628
688
  verts: holePath.verts,
629
689
  prims: holePath.prims,
@@ -634,18 +694,17 @@ var addPillHoleWithRectPad = (platedHole, ctx) => {
634
694
  };
635
695
 
636
696
  // lib/element-handlers/addPlatedHole/addRotatedPillHoleWithRectPad.ts
637
- import { ShapePath as ShapePath5 } from "lbrnts";
697
+ import { ShapePath as ShapePath6 } from "lbrnts";
638
698
  var addRotatedPillHoleWithRectPad = (platedHole, ctx) => {
639
699
  const {
640
700
  project,
641
- topCopperCutSetting,
642
- bottomCopperCutSetting,
643
701
  soldermaskCutSetting,
644
702
  throughBoardCutSetting,
645
703
  origin,
646
704
  includeCopper,
647
705
  includeSoldermask,
648
706
  globalCopperSoldermaskMarginAdjustment,
707
+ solderMaskMarginPercent,
649
708
  includeLayers
650
709
  } = ctx;
651
710
  const centerX = platedHole.x + origin.x;
@@ -665,30 +724,32 @@ var addRotatedPillHoleWithRectPad = (platedHole, ctx) => {
665
724
  rotation: padRotation
666
725
  });
667
726
  if (includeCopper) {
668
- if (includeLayers.includes("top")) {
669
- project.children.push(
670
- new ShapePath5({
671
- cutIndex: topCopperCutSetting.index,
672
- verts: padPath.verts,
673
- prims: padPath.prims,
674
- isClosed: true
675
- })
676
- );
677
- }
678
- if (includeLayers.includes("bottom")) {
679
- project.children.push(
680
- new ShapePath5({
681
- cutIndex: bottomCopperCutSetting.index,
682
- verts: padPath.verts,
683
- prims: padPath.prims,
684
- isClosed: true
685
- })
686
- );
687
- }
727
+ addCopperGeometryToNetOrProject({
728
+ geometryId: platedHole.pcb_plated_hole_id,
729
+ path: padPath,
730
+ layer: "top",
731
+ ctx
732
+ });
733
+ addCopperGeometryToNetOrProject({
734
+ geometryId: platedHole.pcb_plated_hole_id,
735
+ path: padPath,
736
+ layer: "bottom",
737
+ ctx
738
+ });
688
739
  }
689
740
  if (includeSoldermask) {
690
- const smPadWidth = padWidth + 2 * globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
691
- const smPadHeight = padHeight + 2 * globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
741
+ const percentMarginX = solderMaskMarginPercent / 100 * padWidth;
742
+ const percentMarginY = solderMaskMarginPercent / 100 * padHeight;
743
+ const totalMarginX = Math.max(
744
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginX,
745
+ -padWidth / 2
746
+ );
747
+ const totalMarginY = Math.max(
748
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginY,
749
+ -padHeight / 2
750
+ );
751
+ const smPadWidth = padWidth + 2 * totalMarginX;
752
+ const smPadHeight = padHeight + 2 * totalMarginY;
692
753
  const smPadPath = createRoundedRectPath({
693
754
  centerX,
694
755
  centerY,
@@ -699,7 +760,7 @@ var addRotatedPillHoleWithRectPad = (platedHole, ctx) => {
699
760
  rotation: padRotation
700
761
  });
701
762
  project.children.push(
702
- new ShapePath5({
763
+ new ShapePath6({
703
764
  cutIndex: soldermaskCutSetting.index,
704
765
  verts: smPadPath.verts,
705
766
  prims: smPadPath.prims,
@@ -722,7 +783,7 @@ var addRotatedPillHoleWithRectPad = (platedHole, ctx) => {
722
783
  rotation: holeRotation
723
784
  });
724
785
  project.children.push(
725
- new ShapePath5({
786
+ new ShapePath6({
726
787
  cutIndex: throughBoardCutSetting.index,
727
788
  verts: holePath.verts,
728
789
  prims: holePath.prims,
@@ -733,7 +794,7 @@ var addRotatedPillHoleWithRectPad = (platedHole, ctx) => {
733
794
  };
734
795
 
735
796
  // lib/element-handlers/addPlatedHole/addHoleWithPolygonPad.ts
736
- import { ShapePath as ShapePath6 } from "lbrnts";
797
+ import { ShapePath as ShapePath7 } from "lbrnts";
737
798
 
738
799
  // lib/helpers/polygonShape.ts
739
800
  var createPolygonPathFromOutline = ({
@@ -742,9 +803,9 @@ var createPolygonPathFromOutline = ({
742
803
  offsetY
743
804
  }) => {
744
805
  const verts = [];
745
- for (const point6 of outline) {
746
- const x = (point6.x ?? 0) + offsetX;
747
- const y = (point6.y ?? 0) + offsetY;
806
+ for (const point5 of outline) {
807
+ const x = (point5.x ?? 0) + offsetX;
808
+ const y = (point5.y ?? 0) + offsetY;
748
809
  verts.push({ x, y });
749
810
  }
750
811
  if (verts.length === 0) {
@@ -760,8 +821,6 @@ var createPolygonPathFromOutline = ({
760
821
  var addHoleWithPolygonPad = (platedHole, ctx) => {
761
822
  const {
762
823
  project,
763
- topCopperCutSetting,
764
- bottomCopperCutSetting,
765
824
  soldermaskCutSetting,
766
825
  throughBoardCutSetting,
767
826
  origin,
@@ -777,30 +836,22 @@ var addHoleWithPolygonPad = (platedHole, ctx) => {
777
836
  offsetY: platedHole.y + origin.y
778
837
  });
779
838
  if (includeCopper) {
780
- if (includeLayers.includes("top")) {
781
- project.children.push(
782
- new ShapePath6({
783
- cutIndex: topCopperCutSetting.index,
784
- verts: pad.verts,
785
- prims: pad.prims,
786
- isClosed: true
787
- })
788
- );
789
- }
790
- if (includeLayers.includes("bottom")) {
791
- project.children.push(
792
- new ShapePath6({
793
- cutIndex: bottomCopperCutSetting.index,
794
- verts: pad.verts,
795
- prims: pad.prims,
796
- isClosed: true
797
- })
798
- );
799
- }
839
+ addCopperGeometryToNetOrProject({
840
+ geometryId: platedHole.pcb_plated_hole_id,
841
+ path: pad,
842
+ layer: "top",
843
+ ctx
844
+ });
845
+ addCopperGeometryToNetOrProject({
846
+ geometryId: platedHole.pcb_plated_hole_id,
847
+ path: pad,
848
+ layer: "bottom",
849
+ ctx
850
+ });
800
851
  }
801
852
  if (includeSoldermask) {
802
853
  project.children.push(
803
- new ShapePath6({
854
+ new ShapePath7({
804
855
  cutIndex: soldermaskCutSetting.index,
805
856
  verts: pad.verts,
806
857
  prims: pad.prims,
@@ -820,7 +871,7 @@ var addHoleWithPolygonPad = (platedHole, ctx) => {
820
871
  segments: 64
821
872
  });
822
873
  project.children.push(
823
- new ShapePath6({
874
+ new ShapePath7({
824
875
  cutIndex: throughBoardCutSetting.index,
825
876
  verts: hole.verts,
826
877
  prims: hole.prims,
@@ -839,7 +890,7 @@ var addHoleWithPolygonPad = (platedHole, ctx) => {
839
890
  segments: 64
840
891
  });
841
892
  project.children.push(
842
- new ShapePath6({
893
+ new ShapePath7({
843
894
  cutIndex: throughBoardCutSetting.index,
844
895
  verts: hole.verts,
845
896
  prims: hole.prims,
@@ -850,7 +901,7 @@ var addHoleWithPolygonPad = (platedHole, ctx) => {
850
901
  };
851
902
 
852
903
  // lib/element-handlers/addPlatedHole/addPillPlatedHole.ts
853
- import { ShapePath as ShapePath7 } from "lbrnts";
904
+ import { ShapePath as ShapePath8 } from "lbrnts";
854
905
  var addPcbPlatedHolePill = (platedHole, ctx) => {
855
906
  const {
856
907
  project,
@@ -862,6 +913,7 @@ var addPcbPlatedHolePill = (platedHole, ctx) => {
862
913
  includeCopper,
863
914
  includeSoldermask,
864
915
  globalCopperSoldermaskMarginAdjustment,
916
+ solderMaskMarginPercent,
865
917
  includeLayers
866
918
  } = ctx;
867
919
  const centerX = platedHole.x + origin.x;
@@ -877,7 +929,7 @@ var addPcbPlatedHolePill = (platedHole, ctx) => {
877
929
  });
878
930
  if (includeLayers.includes("top")) {
879
931
  project.children.push(
880
- new ShapePath7({
932
+ new ShapePath8({
881
933
  cutIndex: topCopperCutSetting.index,
882
934
  verts: outer.verts,
883
935
  prims: outer.prims,
@@ -887,7 +939,7 @@ var addPcbPlatedHolePill = (platedHole, ctx) => {
887
939
  }
888
940
  if (includeLayers.includes("bottom")) {
889
941
  project.children.push(
890
- new ShapePath7({
942
+ new ShapePath8({
891
943
  cutIndex: bottomCopperCutSetting.index,
892
944
  verts: outer.verts,
893
945
  prims: outer.prims,
@@ -897,8 +949,18 @@ var addPcbPlatedHolePill = (platedHole, ctx) => {
897
949
  }
898
950
  }
899
951
  if (platedHole.outer_width > 0 && platedHole.outer_height > 0 && includeSoldermask) {
900
- const smWidth = platedHole.outer_width + 2 * globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
901
- const smHeight = platedHole.outer_height + 2 * globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0);
952
+ const percentMarginX = solderMaskMarginPercent / 100 * platedHole.outer_width;
953
+ const percentMarginY = solderMaskMarginPercent / 100 * platedHole.outer_height;
954
+ const totalMarginX = Math.max(
955
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginX,
956
+ -platedHole.outer_width / 2
957
+ );
958
+ const totalMarginY = Math.max(
959
+ globalCopperSoldermaskMarginAdjustment + (platedHole.soldermask_margin ?? 0) + percentMarginY,
960
+ -platedHole.outer_height / 2
961
+ );
962
+ const smWidth = platedHole.outer_width + 2 * totalMarginX;
963
+ const smHeight = platedHole.outer_height + 2 * totalMarginY;
902
964
  const outer = createPillPath({
903
965
  centerX,
904
966
  centerY,
@@ -907,7 +969,7 @@ var addPcbPlatedHolePill = (platedHole, ctx) => {
907
969
  rotation
908
970
  });
909
971
  project.children.push(
910
- new ShapePath7({
972
+ new ShapePath8({
911
973
  cutIndex: soldermaskCutSetting.index,
912
974
  verts: outer.verts,
913
975
  prims: outer.prims,
@@ -924,7 +986,7 @@ var addPcbPlatedHolePill = (platedHole, ctx) => {
924
986
  rotation
925
987
  });
926
988
  project.children.push(
927
- new ShapePath7({
989
+ new ShapePath8({
928
990
  cutIndex: throughBoardCutSetting.index,
929
991
  verts: inner.verts,
930
992
  prims: inner.prims,
@@ -958,21 +1020,17 @@ var addPlatedHole = (platedHole, ctx) => {
958
1020
  };
959
1021
 
960
1022
  // lib/element-handlers/addSmtPad/addRectSmtPad.ts
961
- import { Box } from "@flatten-js/core";
962
- import { ShapePath as ShapePath8 } from "lbrnts";
1023
+ import "@flatten-js/core";
1024
+ import { ShapePath as ShapePath9 } from "lbrnts";
963
1025
  var addRectSmtPad = (smtPad, ctx) => {
964
1026
  const {
965
1027
  project,
966
- topCopperCutSetting,
967
- bottomCopperCutSetting,
968
1028
  soldermaskCutSetting,
969
- connMap,
970
- topCutNetGeoms,
971
- bottomCutNetGeoms,
972
1029
  origin,
973
1030
  includeCopper,
974
1031
  includeSoldermask,
975
1032
  globalCopperSoldermaskMarginAdjustment,
1033
+ solderMaskMarginPercent,
976
1034
  includeLayers
977
1035
  } = ctx;
978
1036
  const padLayer = smtPad.layer || "top";
@@ -986,48 +1044,38 @@ var addRectSmtPad = (smtPad, ctx) => {
986
1044
  const centerY = smtPad.y + origin.y;
987
1045
  const halfWidth = smtPad.width / 2;
988
1046
  const halfHeight = smtPad.height / 2;
989
- const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id);
990
- const copperCutSetting = padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting;
991
- const netGeoms = padLayer === "top" ? topCutNetGeoms : bottomCutNetGeoms;
992
1047
  if (includeCopper) {
993
- if (netId) {
994
- netGeoms.get(netId)?.push(
995
- new Box(
996
- centerX - halfWidth,
997
- centerY - halfHeight,
998
- centerX + halfWidth,
999
- centerY + halfHeight
1000
- )
1001
- );
1002
- } else {
1003
- const verts = [
1048
+ const path = {
1049
+ verts: [
1004
1050
  { x: centerX - halfWidth, y: centerY - halfHeight },
1005
1051
  { x: centerX + halfWidth, y: centerY - halfHeight },
1006
1052
  { x: centerX + halfWidth, y: centerY + halfHeight },
1007
1053
  { x: centerX - halfWidth, y: centerY + halfHeight },
1008
1054
  { x: centerX - halfWidth, y: centerY - halfHeight }
1009
1055
  // Close the path
1010
- ];
1011
- const prims = [
1012
- { type: 0 },
1013
- { type: 0 },
1014
- { type: 0 },
1015
- { type: 0 },
1016
- { type: 0 }
1017
- ];
1018
- project.children.push(
1019
- new ShapePath8({
1020
- cutIndex: copperCutSetting.index,
1021
- verts,
1022
- prims,
1023
- isClosed: true
1024
- })
1025
- );
1026
- }
1056
+ ],
1057
+ prims: [{ type: 0 }, { type: 0 }, { type: 0 }, { type: 0 }, { type: 0 }]
1058
+ };
1059
+ addCopperGeometryToNetOrProject({
1060
+ geometryId: smtPad.pcb_smtpad_id,
1061
+ path,
1062
+ layer: padLayer,
1063
+ ctx
1064
+ });
1027
1065
  }
1028
1066
  if (includeSoldermask) {
1029
- const smHalfWidth = halfWidth + globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0);
1030
- const smHalfHeight = halfHeight + globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0);
1067
+ const percentMarginX = solderMaskMarginPercent / 100 * smtPad.width;
1068
+ const percentMarginY = solderMaskMarginPercent / 100 * smtPad.height;
1069
+ const totalMarginX = Math.max(
1070
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginX,
1071
+ -smtPad.width / 2
1072
+ );
1073
+ const totalMarginY = Math.max(
1074
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginY,
1075
+ -smtPad.height / 2
1076
+ );
1077
+ const smHalfWidth = halfWidth + totalMarginX;
1078
+ const smHalfHeight = halfHeight + totalMarginY;
1031
1079
  const verts = [
1032
1080
  { x: centerX - smHalfWidth, y: centerY - smHalfHeight },
1033
1081
  { x: centerX + smHalfWidth, y: centerY - smHalfHeight },
@@ -1044,7 +1092,7 @@ var addRectSmtPad = (smtPad, ctx) => {
1044
1092
  { type: 0 }
1045
1093
  ];
1046
1094
  project.children.push(
1047
- new ShapePath8({
1095
+ new ShapePath9({
1048
1096
  cutIndex: soldermaskCutSetting.index,
1049
1097
  verts,
1050
1098
  prims,
@@ -1055,21 +1103,16 @@ var addRectSmtPad = (smtPad, ctx) => {
1055
1103
  };
1056
1104
 
1057
1105
  // lib/element-handlers/addSmtPad/addCircleSmtPad.ts
1058
- import { ShapePath as ShapePath9 } from "lbrnts";
1059
- import { Circle as Circle2, point as point2 } from "@flatten-js/core";
1106
+ import { ShapePath as ShapePath10 } from "lbrnts";
1060
1107
  var addCircleSmtPad = (smtPad, ctx) => {
1061
1108
  const {
1062
1109
  project,
1063
- topCopperCutSetting,
1064
- bottomCopperCutSetting,
1065
1110
  soldermaskCutSetting,
1066
- topCutNetGeoms,
1067
- bottomCutNetGeoms,
1068
1111
  origin,
1069
1112
  includeCopper,
1070
1113
  includeSoldermask,
1071
- connMap,
1072
1114
  globalCopperSoldermaskMarginAdjustment,
1115
+ solderMaskMarginPercent,
1073
1116
  includeLayers
1074
1117
  } = ctx;
1075
1118
  const padLayer = smtPad.layer || "top";
@@ -1079,43 +1122,44 @@ var addCircleSmtPad = (smtPad, ctx) => {
1079
1122
  if (!includeLayers.includes(padLayer)) {
1080
1123
  return;
1081
1124
  }
1082
- const copperCutSetting = padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting;
1083
- const netGeoms = padLayer === "top" ? topCutNetGeoms : bottomCutNetGeoms;
1084
1125
  const centerX = smtPad.x + origin.x;
1085
1126
  const centerY = smtPad.y + origin.y;
1086
1127
  if (smtPad.radius > 0) {
1087
1128
  const outerRadius = smtPad.radius;
1088
1129
  if (includeCopper) {
1089
- const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id);
1090
- const circle = new Circle2(point2(centerX, centerY), outerRadius);
1091
- const polygon = circleToPolygon(circle);
1092
- if (netId) {
1093
- netGeoms.get(netId)?.push(polygon);
1094
- } else {
1095
- const outer = createCirclePath({
1096
- centerX,
1097
- centerY,
1098
- radius: outerRadius
1099
- });
1100
- project.children.push(
1101
- new ShapePath9({
1102
- cutIndex: copperCutSetting.index,
1103
- verts: outer.verts,
1104
- prims: outer.prims,
1105
- isClosed: true
1106
- })
1107
- );
1108
- }
1130
+ const path = createCirclePath({
1131
+ centerX,
1132
+ centerY,
1133
+ radius: outerRadius
1134
+ });
1135
+ addCopperGeometryToNetOrProject({
1136
+ geometryId: smtPad.pcb_smtpad_id,
1137
+ path,
1138
+ layer: padLayer,
1139
+ ctx
1140
+ });
1109
1141
  }
1110
1142
  if (includeSoldermask) {
1111
- const smRadius = outerRadius + globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0);
1143
+ const elementWidth = 2 * outerRadius;
1144
+ const elementHeight = 2 * outerRadius;
1145
+ const percentMarginX = solderMaskMarginPercent / 100 * elementWidth;
1146
+ const percentMarginY = solderMaskMarginPercent / 100 * elementHeight;
1147
+ const totalMarginX = Math.max(
1148
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginX,
1149
+ -elementWidth / 2
1150
+ );
1151
+ const totalMarginY = Math.max(
1152
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginY,
1153
+ -elementHeight / 2
1154
+ );
1155
+ const smRadius = outerRadius + totalMarginX;
1112
1156
  const outer = createCirclePath({
1113
1157
  centerX,
1114
1158
  centerY,
1115
1159
  radius: smRadius
1116
1160
  });
1117
1161
  project.children.push(
1118
- new ShapePath9({
1162
+ new ShapePath10({
1119
1163
  cutIndex: soldermaskCutSetting.index,
1120
1164
  verts: outer.verts,
1121
1165
  prims: outer.prims,
@@ -1127,29 +1171,16 @@ var addCircleSmtPad = (smtPad, ctx) => {
1127
1171
  };
1128
1172
 
1129
1173
  // lib/element-handlers/addSmtPad/addPillSmtPad.ts
1130
- import { ShapePath as ShapePath10 } from "lbrnts";
1131
-
1132
- // lib/helpers/pathToPolygon.ts
1133
- import { Polygon as Polygon2, point as point3 } from "@flatten-js/core";
1134
- var pathToPolygon = (verts) => {
1135
- const points = verts.map((v) => point3(v.x, v.y));
1136
- return new Polygon2(points);
1137
- };
1138
-
1139
- // lib/element-handlers/addSmtPad/addPillSmtPad.ts
1174
+ import { ShapePath as ShapePath11 } from "lbrnts";
1140
1175
  var addPillSmtPad = (smtPad, ctx) => {
1141
1176
  const {
1142
1177
  project,
1143
- topCopperCutSetting,
1144
- bottomCopperCutSetting,
1145
1178
  soldermaskCutSetting,
1146
- topCutNetGeoms,
1147
- bottomCutNetGeoms,
1148
1179
  origin,
1149
1180
  includeCopper,
1150
1181
  includeSoldermask,
1151
- connMap,
1152
1182
  globalCopperSoldermaskMarginAdjustment,
1183
+ solderMaskMarginPercent,
1153
1184
  includeLayers
1154
1185
  } = ctx;
1155
1186
  const padLayer = smtPad.layer || "top";
@@ -1159,8 +1190,6 @@ var addPillSmtPad = (smtPad, ctx) => {
1159
1190
  if (!includeLayers.includes(padLayer)) {
1160
1191
  return;
1161
1192
  }
1162
- const copperCutSetting = padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting;
1163
- const netGeoms = padLayer === "top" ? topCutNetGeoms : bottomCutNetGeoms;
1164
1193
  const centerX = smtPad.x + origin.x;
1165
1194
  const centerY = smtPad.y + origin.y;
1166
1195
  if (smtPad.width > 0 && smtPad.height > 0) {
@@ -1171,24 +1200,26 @@ var addPillSmtPad = (smtPad, ctx) => {
1171
1200
  height: smtPad.height
1172
1201
  });
1173
1202
  if (includeCopper) {
1174
- const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id);
1175
- const polygon = pathToPolygon(outer.verts);
1176
- if (netId) {
1177
- netGeoms.get(netId)?.push(polygon);
1178
- } else {
1179
- project.children.push(
1180
- new ShapePath10({
1181
- cutIndex: copperCutSetting.index,
1182
- verts: outer.verts,
1183
- prims: outer.prims,
1184
- isClosed: true
1185
- })
1186
- );
1187
- }
1203
+ addCopperGeometryToNetOrProject({
1204
+ geometryId: smtPad.pcb_smtpad_id,
1205
+ path: outer,
1206
+ layer: padLayer,
1207
+ ctx
1208
+ });
1188
1209
  }
1189
1210
  if (includeSoldermask) {
1190
- const smWidth = smtPad.width + 2 * globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0);
1191
- const smHeight = smtPad.height + 2 * globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0);
1211
+ const percentMarginX = solderMaskMarginPercent / 100 * smtPad.width;
1212
+ const percentMarginY = solderMaskMarginPercent / 100 * smtPad.height;
1213
+ const totalMarginX = Math.max(
1214
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginX,
1215
+ -smtPad.width / 2
1216
+ );
1217
+ const totalMarginY = Math.max(
1218
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginY,
1219
+ -smtPad.height / 2
1220
+ );
1221
+ const smWidth = smtPad.width + 2 * totalMarginX;
1222
+ const smHeight = smtPad.height + 2 * totalMarginY;
1192
1223
  const smOuter = createPillPath({
1193
1224
  centerX,
1194
1225
  centerY,
@@ -1196,7 +1227,7 @@ var addPillSmtPad = (smtPad, ctx) => {
1196
1227
  height: smHeight
1197
1228
  });
1198
1229
  project.children.push(
1199
- new ShapePath10({
1230
+ new ShapePath11({
1200
1231
  cutIndex: soldermaskCutSetting.index,
1201
1232
  verts: smOuter.verts,
1202
1233
  prims: smOuter.prims,
@@ -1208,20 +1239,16 @@ var addPillSmtPad = (smtPad, ctx) => {
1208
1239
  };
1209
1240
 
1210
1241
  // lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts
1211
- import { ShapePath as ShapePath11 } from "lbrnts";
1242
+ import { ShapePath as ShapePath12 } from "lbrnts";
1212
1243
  var addRotatedPillSmtPad = (smtPad, ctx) => {
1213
1244
  const {
1214
1245
  project,
1215
- topCopperCutSetting,
1216
- bottomCopperCutSetting,
1217
1246
  soldermaskCutSetting,
1218
- topCutNetGeoms,
1219
- bottomCutNetGeoms,
1220
1247
  origin,
1221
1248
  includeCopper,
1222
1249
  includeSoldermask,
1223
- connMap,
1224
1250
  globalCopperSoldermaskMarginAdjustment,
1251
+ solderMaskMarginPercent,
1225
1252
  includeLayers
1226
1253
  } = ctx;
1227
1254
  const padLayer = smtPad.layer || "top";
@@ -1231,8 +1258,6 @@ var addRotatedPillSmtPad = (smtPad, ctx) => {
1231
1258
  if (!includeLayers.includes(padLayer)) {
1232
1259
  return;
1233
1260
  }
1234
- const copperCutSetting = padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting;
1235
- const netGeoms = padLayer === "top" ? topCutNetGeoms : bottomCutNetGeoms;
1236
1261
  const centerX = smtPad.x + origin.x;
1237
1262
  const centerY = smtPad.y + origin.y;
1238
1263
  if (smtPad.width > 0 && smtPad.height > 0) {
@@ -1244,24 +1269,26 @@ var addRotatedPillSmtPad = (smtPad, ctx) => {
1244
1269
  rotation: (smtPad.ccw_rotation ?? 0) * (Math.PI / 180)
1245
1270
  });
1246
1271
  if (includeCopper) {
1247
- const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id);
1248
- const polygon = pathToPolygon(outer.verts);
1249
- if (netId) {
1250
- netGeoms.get(netId)?.push(polygon);
1251
- } else {
1252
- project.children.push(
1253
- new ShapePath11({
1254
- cutIndex: copperCutSetting.index,
1255
- verts: outer.verts,
1256
- prims: outer.prims,
1257
- isClosed: true
1258
- })
1259
- );
1260
- }
1272
+ addCopperGeometryToNetOrProject({
1273
+ geometryId: smtPad.pcb_smtpad_id,
1274
+ path: outer,
1275
+ layer: padLayer,
1276
+ ctx
1277
+ });
1261
1278
  }
1262
1279
  if (includeSoldermask) {
1263
- const smWidth = smtPad.width + 2 * globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0);
1264
- const smHeight = smtPad.height + 2 * globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0);
1280
+ const percentMarginX = solderMaskMarginPercent / 100 * smtPad.width;
1281
+ const percentMarginY = solderMaskMarginPercent / 100 * smtPad.height;
1282
+ const totalMarginX = Math.max(
1283
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginX,
1284
+ -smtPad.width / 2
1285
+ );
1286
+ const totalMarginY = Math.max(
1287
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginY,
1288
+ -smtPad.height / 2
1289
+ );
1290
+ const smWidth = smtPad.width + 2 * totalMarginX;
1291
+ const smHeight = smtPad.height + 2 * totalMarginY;
1265
1292
  const smOuter = createPillPath({
1266
1293
  centerX,
1267
1294
  centerY,
@@ -1270,7 +1297,7 @@ var addRotatedPillSmtPad = (smtPad, ctx) => {
1270
1297
  rotation: (smtPad.ccw_rotation ?? 0) * (Math.PI / 180)
1271
1298
  });
1272
1299
  project.children.push(
1273
- new ShapePath11({
1300
+ new ShapePath12({
1274
1301
  cutIndex: soldermaskCutSetting.index,
1275
1302
  verts: smOuter.verts,
1276
1303
  prims: smOuter.prims,
@@ -1282,7 +1309,7 @@ var addRotatedPillSmtPad = (smtPad, ctx) => {
1282
1309
  };
1283
1310
 
1284
1311
  // lib/element-handlers/addSmtPad/addPolygonSmtPad.ts
1285
- import { ShapePath as ShapePath12 } from "lbrnts";
1312
+ import { ShapePath as ShapePath13 } from "lbrnts";
1286
1313
 
1287
1314
  // lib/polygon-to-shape-path.ts
1288
1315
  function polygonToShapePathData(polygon) {
@@ -1315,16 +1342,12 @@ function polygonToShapePathData(polygon) {
1315
1342
  var addPolygonSmtPad = (smtPad, ctx) => {
1316
1343
  const {
1317
1344
  project,
1318
- topCopperCutSetting,
1319
- bottomCopperCutSetting,
1320
1345
  soldermaskCutSetting,
1321
- topCutNetGeoms,
1322
- bottomCutNetGeoms,
1323
1346
  origin,
1324
1347
  includeCopper,
1325
1348
  includeSoldermask,
1326
- connMap,
1327
1349
  globalCopperSoldermaskMarginAdjustment,
1350
+ solderMaskMarginPercent,
1328
1351
  includeLayers
1329
1352
  } = ctx;
1330
1353
  const padLayer = smtPad.layer || "top";
@@ -1334,8 +1357,6 @@ var addPolygonSmtPad = (smtPad, ctx) => {
1334
1357
  if (!includeLayers.includes(padLayer)) {
1335
1358
  return;
1336
1359
  }
1337
- const copperCutSetting = padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting;
1338
- const netGeoms = padLayer === "top" ? topCutNetGeoms : bottomCutNetGeoms;
1339
1360
  if (smtPad.points.length >= 3) {
1340
1361
  const pad = createPolygonPathFromOutline({
1341
1362
  outline: smtPad.points,
@@ -1343,24 +1364,16 @@ var addPolygonSmtPad = (smtPad, ctx) => {
1343
1364
  offsetY: origin.y
1344
1365
  });
1345
1366
  if (includeCopper) {
1346
- const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id);
1347
- const polygon = pathToPolygon(pad.verts);
1348
- if (netId) {
1349
- netGeoms.get(netId)?.push(polygon);
1350
- } else {
1351
- project.children.push(
1352
- new ShapePath12({
1353
- cutIndex: copperCutSetting.index,
1354
- verts: pad.verts,
1355
- prims: pad.prims,
1356
- isClosed: true
1357
- })
1358
- );
1359
- }
1367
+ addCopperGeometryToNetOrProject({
1368
+ geometryId: smtPad.pcb_smtpad_id,
1369
+ path: pad,
1370
+ layer: padLayer,
1371
+ ctx
1372
+ });
1360
1373
  }
1361
1374
  if (includeSoldermask) {
1362
1375
  project.children.push(
1363
- new ShapePath12({
1376
+ new ShapePath13({
1364
1377
  cutIndex: soldermaskCutSetting.index,
1365
1378
  verts: pad.verts,
1366
1379
  prims: pad.prims,
@@ -1372,20 +1385,16 @@ var addPolygonSmtPad = (smtPad, ctx) => {
1372
1385
  };
1373
1386
 
1374
1387
  // lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts
1375
- import { ShapePath as ShapePath13 } from "lbrnts";
1388
+ import { ShapePath as ShapePath14 } from "lbrnts";
1376
1389
  var addRotatedRectSmtPad = (smtPad, ctx) => {
1377
1390
  const {
1378
1391
  project,
1379
- topCopperCutSetting,
1380
- bottomCopperCutSetting,
1381
1392
  soldermaskCutSetting,
1382
- topCutNetGeoms,
1383
- bottomCutNetGeoms,
1384
1393
  origin,
1385
1394
  includeCopper,
1386
1395
  includeSoldermask,
1387
- connMap,
1388
1396
  globalCopperSoldermaskMarginAdjustment,
1397
+ solderMaskMarginPercent,
1389
1398
  includeLayers
1390
1399
  } = ctx;
1391
1400
  const padLayer = smtPad.layer || "top";
@@ -1395,8 +1404,6 @@ var addRotatedRectSmtPad = (smtPad, ctx) => {
1395
1404
  if (!includeLayers.includes(padLayer)) {
1396
1405
  return;
1397
1406
  }
1398
- const copperCutSetting = padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting;
1399
- const netGeoms = padLayer === "top" ? topCutNetGeoms : bottomCutNetGeoms;
1400
1407
  const centerX = smtPad.x + origin.x;
1401
1408
  const centerY = smtPad.y + origin.y;
1402
1409
  const rotation = (smtPad.ccw_rotation ?? 0) * (Math.PI / 180);
@@ -1412,24 +1419,26 @@ var addRotatedRectSmtPad = (smtPad, ctx) => {
1412
1419
  rotation
1413
1420
  });
1414
1421
  if (includeCopper) {
1415
- const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id);
1416
- const polygon = pathToPolygon(outer.verts);
1417
- if (netId) {
1418
- netGeoms.get(netId)?.push(polygon);
1419
- } else {
1420
- project.children.push(
1421
- new ShapePath13({
1422
- cutIndex: copperCutSetting.index,
1423
- verts: outer.verts,
1424
- prims: outer.prims,
1425
- isClosed: true
1426
- })
1427
- );
1428
- }
1422
+ addCopperGeometryToNetOrProject({
1423
+ geometryId: smtPad.pcb_smtpad_id,
1424
+ path: outer,
1425
+ layer: padLayer,
1426
+ ctx
1427
+ });
1429
1428
  }
1430
1429
  if (includeSoldermask) {
1431
- const smWidth = smtPad.width + 2 * globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0);
1432
- const smHeight = smtPad.height + 2 * globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0);
1430
+ const percentMarginX = solderMaskMarginPercent / 100 * smtPad.width;
1431
+ const percentMarginY = solderMaskMarginPercent / 100 * smtPad.height;
1432
+ const totalMarginX = Math.max(
1433
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginX,
1434
+ -smtPad.width / 2
1435
+ );
1436
+ const totalMarginY = Math.max(
1437
+ globalCopperSoldermaskMarginAdjustment + (smtPad.soldermask_margin ?? 0) + percentMarginY,
1438
+ -smtPad.height / 2
1439
+ );
1440
+ const smWidth = smtPad.width + 2 * totalMarginX;
1441
+ const smHeight = smtPad.height + 2 * totalMarginY;
1433
1442
  const smOuter = createRoundedRectPath({
1434
1443
  centerX,
1435
1444
  centerY,
@@ -1440,7 +1449,7 @@ var addRotatedRectSmtPad = (smtPad, ctx) => {
1440
1449
  rotation
1441
1450
  });
1442
1451
  project.children.push(
1443
- new ShapePath13({
1452
+ new ShapePath14({
1444
1453
  cutIndex: soldermaskCutSetting.index,
1445
1454
  verts: smOuter.verts,
1446
1455
  prims: smOuter.prims,
@@ -1479,8 +1488,8 @@ var splitRouteSegmentsByLayer = (trace) => {
1479
1488
  }
1480
1489
  let currentSegment = [];
1481
1490
  let currentLayer = null;
1482
- for (const point6 of trace.route) {
1483
- if ("route_type" in point6 && point6.route_type === "via") {
1491
+ for (const point5 of trace.route) {
1492
+ if ("route_type" in point5 && point5.route_type === "via") {
1484
1493
  if (currentLayer && currentSegment.length > 0) {
1485
1494
  if (!layerSegments.has(currentLayer)) {
1486
1495
  layerSegments.set(currentLayer, []);
@@ -1491,9 +1500,9 @@ var splitRouteSegmentsByLayer = (trace) => {
1491
1500
  currentLayer = null;
1492
1501
  continue;
1493
1502
  }
1494
- const isWirePoint = !("route_type" in point6) || point6.route_type === "wire";
1495
- if (isWirePoint && "layer" in point6 && point6.layer) {
1496
- const pointLayer = point6.layer;
1503
+ const isWirePoint = !("route_type" in point5) || point5.route_type === "wire";
1504
+ if (isWirePoint && "layer" in point5 && point5.layer) {
1505
+ const pointLayer = point5.layer;
1497
1506
  if (pointLayer !== "top" && pointLayer !== "bottom") {
1498
1507
  continue;
1499
1508
  }
@@ -1507,7 +1516,7 @@ var splitRouteSegmentsByLayer = (trace) => {
1507
1516
  currentSegment = [];
1508
1517
  }
1509
1518
  currentLayer = pointLayer;
1510
- currentSegment.push({ x: point6.x, y: point6.y });
1519
+ currentSegment.push({ x: point5.x, y: point5.y });
1511
1520
  }
1512
1521
  }
1513
1522
  if (currentLayer && currentSegment.length > 0) {
@@ -1743,9 +1752,9 @@ var addPcbTrace = (trace, ctx) => {
1743
1752
  if (!trace.route || trace.route.length < 2) {
1744
1753
  return;
1745
1754
  }
1746
- const wirePoint = trace.route.find((point6) => {
1747
- if (!("route_type" in point6)) return true;
1748
- return point6.route_type === "wire";
1755
+ const wirePoint = trace.route.find((point5) => {
1756
+ if (!("route_type" in point5)) return true;
1757
+ return point5.route_type === "wire";
1749
1758
  });
1750
1759
  const traceWidth = wirePoint?.width ?? 0.15;
1751
1760
  const layerSegments = splitRouteSegmentsByLayer(trace);
@@ -1816,8 +1825,8 @@ var addPcbTrace = (trace, ctx) => {
1816
1825
  };
1817
1826
 
1818
1827
  // lib/element-handlers/addPcbBoard/index.ts
1819
- import { Polygon as Polygon3, point as point4 } from "@flatten-js/core";
1820
- import { ShapePath as ShapePath14 } from "lbrnts";
1828
+ import { Polygon as Polygon2, point as point3 } from "@flatten-js/core";
1829
+ import { ShapePath as ShapePath15 } from "lbrnts";
1821
1830
  var addPcbBoard = (board, ctx) => {
1822
1831
  const {
1823
1832
  origin,
@@ -1829,9 +1838,9 @@ var addPcbBoard = (board, ctx) => {
1829
1838
  } = ctx;
1830
1839
  let polygon = null;
1831
1840
  if (board.outline?.length) {
1832
- polygon = new Polygon3(
1841
+ polygon = new Polygon2(
1833
1842
  board.outline.map(
1834
- (outlinePoint) => point4(outlinePoint.x + origin.x, outlinePoint.y + origin.y)
1843
+ (outlinePoint) => point3(outlinePoint.x + origin.x, outlinePoint.y + origin.y)
1835
1844
  )
1836
1845
  );
1837
1846
  } else if (typeof board.width === "number" && typeof board.height === "number" && board.center) {
@@ -1841,18 +1850,18 @@ var addPcbBoard = (board, ctx) => {
1841
1850
  const minY = board.center.y - halfHeight + origin.y;
1842
1851
  const maxX = board.center.x + halfWidth + origin.x;
1843
1852
  const maxY = board.center.y + halfHeight + origin.y;
1844
- polygon = new Polygon3([
1845
- point4(minX, minY),
1846
- point4(maxX, minY),
1847
- point4(maxX, maxY),
1848
- point4(minX, maxY)
1853
+ polygon = new Polygon2([
1854
+ point3(minX, minY),
1855
+ point3(maxX, minY),
1856
+ point3(maxX, maxY),
1857
+ point3(minX, maxY)
1849
1858
  ]);
1850
1859
  }
1851
1860
  if (!polygon) return;
1852
1861
  const { verts, prims } = polygonToShapePathData(polygon);
1853
1862
  if (includeCopper) {
1854
1863
  project.children.push(
1855
- new ShapePath14({
1864
+ new ShapePath15({
1856
1865
  cutIndex: throughBoardCutSetting.index,
1857
1866
  verts,
1858
1867
  prims,
@@ -1890,14 +1899,14 @@ var calculateCircuitBounds = (circuitJson) => {
1890
1899
  }
1891
1900
  }
1892
1901
  for (const trace of db.pcb_trace.list()) {
1893
- const isWidthPoint = (point6) => "width" in point6 && typeof point6.width === "number";
1902
+ const isWidthPoint = (point5) => "width" in point5 && typeof point5.width === "number";
1894
1903
  const halfWidth = trace.route_thickness_mode === "interpolated" ? 0 : (trace.route.find(isWidthPoint)?.width ?? 0) / 2;
1895
- for (const point6 of trace.route) {
1896
- const pointWidth = trace.route_thickness_mode === "interpolated" ? isWidthPoint(point6) ? point6.width / 2 : 0 : halfWidth;
1897
- minX = Math.min(minX, point6.x - pointWidth);
1898
- minY = Math.min(minY, point6.y - pointWidth);
1899
- maxX = Math.max(maxX, point6.x + pointWidth);
1900
- maxY = Math.max(maxY, point6.y + pointWidth);
1904
+ for (const point5 of trace.route) {
1905
+ const pointWidth = trace.route_thickness_mode === "interpolated" ? isWidthPoint(point5) ? point5.width / 2 : 0 : halfWidth;
1906
+ minX = Math.min(minX, point5.x - pointWidth);
1907
+ minY = Math.min(minY, point5.y - pointWidth);
1908
+ maxX = Math.max(maxX, point5.x + pointWidth);
1909
+ maxY = Math.max(maxY, point5.y + pointWidth);
1901
1910
  }
1902
1911
  }
1903
1912
  for (const hole of db.pcb_plated_hole.list()) {
@@ -1922,8 +1931,8 @@ var calculateOriginFromBounds = (bounds, margin) => {
1922
1931
  };
1923
1932
 
1924
1933
  // lib/element-handlers/addPcbVia/index.ts
1925
- import { ShapePath as ShapePath15 } from "lbrnts";
1926
- import { Circle as Circle3, point as point5 } from "@flatten-js/core";
1934
+ import { ShapePath as ShapePath16 } from "lbrnts";
1935
+ import { Circle as Circle2, point as point4 } from "@flatten-js/core";
1927
1936
  var addPcbVia = (via, ctx) => {
1928
1937
  const {
1929
1938
  db,
@@ -1939,6 +1948,7 @@ var addPcbVia = (via, ctx) => {
1939
1948
  includeSoldermask,
1940
1949
  connMap,
1941
1950
  globalCopperSoldermaskMarginAdjustment,
1951
+ solderMaskMarginPercent,
1942
1952
  includeLayers
1943
1953
  } = ctx;
1944
1954
  const centerX = via.x + origin.x;
@@ -1955,7 +1965,7 @@ var addPcbVia = (via, ctx) => {
1955
1965
  }
1956
1966
  }
1957
1967
  const outerRadius = via.outer_diameter / 2;
1958
- const circle = new Circle3(point5(centerX, centerY), outerRadius);
1968
+ const circle = new Circle2(point4(centerX, centerY), outerRadius);
1959
1969
  const polygon = circleToPolygon(circle);
1960
1970
  if (netId) {
1961
1971
  if (includeLayers.includes("top")) {
@@ -1972,7 +1982,7 @@ var addPcbVia = (via, ctx) => {
1972
1982
  });
1973
1983
  if (includeLayers.includes("top")) {
1974
1984
  project.children.push(
1975
- new ShapePath15({
1985
+ new ShapePath16({
1976
1986
  cutIndex: topCopperCutSetting.index,
1977
1987
  verts: outer.verts,
1978
1988
  prims: outer.prims,
@@ -1982,7 +1992,7 @@ var addPcbVia = (via, ctx) => {
1982
1992
  }
1983
1993
  if (includeLayers.includes("bottom")) {
1984
1994
  project.children.push(
1985
- new ShapePath15({
1995
+ new ShapePath16({
1986
1996
  cutIndex: bottomCopperCutSetting.index,
1987
1997
  verts: outer.verts,
1988
1998
  prims: outer.prims,
@@ -1993,14 +2003,16 @@ var addPcbVia = (via, ctx) => {
1993
2003
  }
1994
2004
  }
1995
2005
  if (via.outer_diameter > 0 && includeSoldermask) {
1996
- const smRadius = via.outer_diameter / 2 + globalCopperSoldermaskMarginAdjustment;
2006
+ const percentMargin = solderMaskMarginPercent / 100 * via.outer_diameter;
2007
+ const totalMargin = globalCopperSoldermaskMarginAdjustment + percentMargin;
2008
+ const smRadius = Math.max(via.outer_diameter / 2 + totalMargin, 0);
1997
2009
  const outer = createCirclePath({
1998
2010
  centerX,
1999
2011
  centerY,
2000
2012
  radius: smRadius
2001
2013
  });
2002
2014
  project.children.push(
2003
- new ShapePath15({
2015
+ new ShapePath16({
2004
2016
  cutIndex: soldermaskCutSetting.index,
2005
2017
  verts: outer.verts,
2006
2018
  prims: outer.prims,
@@ -2016,7 +2028,7 @@ var addPcbVia = (via, ctx) => {
2016
2028
  radius: innerRadius
2017
2029
  });
2018
2030
  project.children.push(
2019
- new ShapePath15({
2031
+ new ShapePath16({
2020
2032
  cutIndex: throughBoardCutSetting.index,
2021
2033
  verts: inner.verts,
2022
2034
  prims: inner.prims,
@@ -2027,7 +2039,7 @@ var addPcbVia = (via, ctx) => {
2027
2039
  };
2028
2040
 
2029
2041
  // lib/element-handlers/addPcbHole/addCirclePcbHole.ts
2030
- import { ShapePath as ShapePath16 } from "lbrnts";
2042
+ import { ShapePath as ShapePath17 } from "lbrnts";
2031
2043
  var addCirclePcbHole = (hole, ctx) => {
2032
2044
  const { project, throughBoardCutSetting, origin, includeCopper } = ctx;
2033
2045
  const centerX = hole.x + origin.x;
@@ -2040,7 +2052,7 @@ var addCirclePcbHole = (hole, ctx) => {
2040
2052
  radius
2041
2053
  });
2042
2054
  project.children.push(
2043
- new ShapePath16({
2055
+ new ShapePath17({
2044
2056
  cutIndex: throughBoardCutSetting.index,
2045
2057
  verts: circlePath.verts,
2046
2058
  prims: circlePath.prims,
@@ -2051,7 +2063,7 @@ var addCirclePcbHole = (hole, ctx) => {
2051
2063
  };
2052
2064
 
2053
2065
  // lib/element-handlers/addPcbHole/addRectPcbHole.ts
2054
- import { ShapePath as ShapePath17 } from "lbrnts";
2066
+ import { ShapePath as ShapePath18 } from "lbrnts";
2055
2067
  var addRectPcbHole = (hole, ctx) => {
2056
2068
  const { project, throughBoardCutSetting, origin, includeCopper } = ctx;
2057
2069
  const centerX = hole.x + origin.x;
@@ -2066,7 +2078,7 @@ var addRectPcbHole = (hole, ctx) => {
2066
2078
  // no border radius for rect holes
2067
2079
  });
2068
2080
  project.children.push(
2069
- new ShapePath17({
2081
+ new ShapePath18({
2070
2082
  cutIndex: throughBoardCutSetting.index,
2071
2083
  verts: rectPath.verts,
2072
2084
  prims: rectPath.prims,
@@ -2077,7 +2089,7 @@ var addRectPcbHole = (hole, ctx) => {
2077
2089
  };
2078
2090
 
2079
2091
  // lib/element-handlers/addPcbHole/addOvalPcbHole.ts
2080
- import { ShapePath as ShapePath18 } from "lbrnts";
2092
+ import { ShapePath as ShapePath19 } from "lbrnts";
2081
2093
  var addOvalPcbHole = (hole, ctx) => {
2082
2094
  const { project, throughBoardCutSetting, origin, includeCopper } = ctx;
2083
2095
  const centerX = hole.x + origin.x;
@@ -2090,7 +2102,7 @@ var addOvalPcbHole = (hole, ctx) => {
2090
2102
  height: hole.hole_height
2091
2103
  });
2092
2104
  project.children.push(
2093
- new ShapePath18({
2105
+ new ShapePath19({
2094
2106
  cutIndex: throughBoardCutSetting.index,
2095
2107
  verts: ovalPath.verts,
2096
2108
  prims: ovalPath.prims,
@@ -2101,7 +2113,7 @@ var addOvalPcbHole = (hole, ctx) => {
2101
2113
  };
2102
2114
 
2103
2115
  // lib/element-handlers/addPcbHole/addPillPcbHole.ts
2104
- import { ShapePath as ShapePath19 } from "lbrnts";
2116
+ import { ShapePath as ShapePath20 } from "lbrnts";
2105
2117
  var addPillPcbHole = (hole, ctx) => {
2106
2118
  const { project, throughBoardCutSetting, origin, includeCopper } = ctx;
2107
2119
  const centerX = hole.x + origin.x;
@@ -2114,7 +2126,7 @@ var addPillPcbHole = (hole, ctx) => {
2114
2126
  height: hole.hole_height
2115
2127
  });
2116
2128
  project.children.push(
2117
- new ShapePath19({
2129
+ new ShapePath20({
2118
2130
  cutIndex: throughBoardCutSetting.index,
2119
2131
  verts: pillPath.verts,
2120
2132
  prims: pillPath.prims,
@@ -2125,7 +2137,7 @@ var addPillPcbHole = (hole, ctx) => {
2125
2137
  };
2126
2138
 
2127
2139
  // lib/element-handlers/addPcbHole/addRotatedPillPcbHole.ts
2128
- import { ShapePath as ShapePath20 } from "lbrnts";
2140
+ import { ShapePath as ShapePath21 } from "lbrnts";
2129
2141
  var addRotatedPillPcbHole = (hole, ctx) => {
2130
2142
  const { project, throughBoardCutSetting, origin, includeCopper } = ctx;
2131
2143
  const centerX = hole.x + origin.x;
@@ -2140,7 +2152,7 @@ var addRotatedPillPcbHole = (hole, ctx) => {
2140
2152
  rotation
2141
2153
  });
2142
2154
  project.children.push(
2143
- new ShapePath20({
2155
+ new ShapePath21({
2144
2156
  cutIndex: throughBoardCutSetting.index,
2145
2157
  verts: pillPath.verts,
2146
2158
  prims: pillPath.prims,
@@ -2171,7 +2183,7 @@ var addPcbHole = (hole, ctx) => {
2171
2183
  };
2172
2184
 
2173
2185
  // lib/element-handlers/addPcbCutout/addCirclePcbCutout.ts
2174
- import { ShapePath as ShapePath21 } from "lbrnts";
2186
+ import { ShapePath as ShapePath22 } from "lbrnts";
2175
2187
  var addCirclePcbCutout = (cutout, ctx) => {
2176
2188
  const { project, throughBoardCutSetting, origin, includeCopper } = ctx;
2177
2189
  const centerX = cutout.center.x + origin.x;
@@ -2183,7 +2195,7 @@ var addCirclePcbCutout = (cutout, ctx) => {
2183
2195
  radius: cutout.radius
2184
2196
  });
2185
2197
  project.children.push(
2186
- new ShapePath21({
2198
+ new ShapePath22({
2187
2199
  cutIndex: throughBoardCutSetting.index,
2188
2200
  verts: circlePath.verts,
2189
2201
  prims: circlePath.prims,
@@ -2194,7 +2206,7 @@ var addCirclePcbCutout = (cutout, ctx) => {
2194
2206
  };
2195
2207
 
2196
2208
  // lib/element-handlers/addPcbCutout/addRectPcbCutout.ts
2197
- import { ShapePath as ShapePath22 } from "lbrnts";
2209
+ import { ShapePath as ShapePath23 } from "lbrnts";
2198
2210
  var addRectPcbCutout = (cutout, ctx) => {
2199
2211
  const { project, throughBoardCutSetting, origin, includeCopper } = ctx;
2200
2212
  const centerX = cutout.center.x + origin.x;
@@ -2213,7 +2225,7 @@ var addRectPcbCutout = (cutout, ctx) => {
2213
2225
  rotation
2214
2226
  });
2215
2227
  project.children.push(
2216
- new ShapePath22({
2228
+ new ShapePath23({
2217
2229
  cutIndex: throughBoardCutSetting.index,
2218
2230
  verts: rectPath.verts,
2219
2231
  prims: rectPath.prims,
@@ -2224,7 +2236,7 @@ var addRectPcbCutout = (cutout, ctx) => {
2224
2236
  };
2225
2237
 
2226
2238
  // lib/element-handlers/addPcbCutout/addPolygonPcbCutout.ts
2227
- import { ShapePath as ShapePath23 } from "lbrnts";
2239
+ import { ShapePath as ShapePath24 } from "lbrnts";
2228
2240
  var addPolygonPcbCutout = (cutout, ctx) => {
2229
2241
  const { project, throughBoardCutSetting, origin, includeCopper } = ctx;
2230
2242
  if (cutout.points.length >= 3 && includeCopper) {
@@ -2234,7 +2246,7 @@ var addPolygonPcbCutout = (cutout, ctx) => {
2234
2246
  offsetY: origin.y
2235
2247
  });
2236
2248
  project.children.push(
2237
- new ShapePath23({
2249
+ new ShapePath24({
2238
2250
  cutIndex: throughBoardCutSetting.index,
2239
2251
  verts: polygonPath.verts,
2240
2252
  prims: polygonPath.prims,
@@ -2245,21 +2257,21 @@ var addPolygonPcbCutout = (cutout, ctx) => {
2245
2257
  };
2246
2258
 
2247
2259
  // lib/element-handlers/addPcbCutout/addPathPcbCutout.ts
2248
- import { ShapePath as ShapePath24 } from "lbrnts";
2260
+ import { ShapePath as ShapePath25 } from "lbrnts";
2249
2261
  var addPathPcbCutout = (cutout, ctx) => {
2250
2262
  const { project, throughBoardCutSetting, origin, includeCopper } = ctx;
2251
2263
  if (cutout.route.length >= 2 && includeCopper) {
2252
2264
  const verts = [];
2253
2265
  const prims = [];
2254
- for (const point6 of cutout.route) {
2266
+ for (const point5 of cutout.route) {
2255
2267
  verts.push({
2256
- x: point6.x + origin.x,
2257
- y: point6.y + origin.y
2268
+ x: point5.x + origin.x,
2269
+ y: point5.y + origin.y
2258
2270
  });
2259
2271
  prims.push({ type: 0 });
2260
2272
  }
2261
2273
  project.children.push(
2262
- new ShapePath24({
2274
+ new ShapePath25({
2263
2275
  cutIndex: throughBoardCutSetting.index,
2264
2276
  verts,
2265
2277
  prims,
@@ -2288,8 +2300,8 @@ var addPcbCutout = (cutout, ctx) => {
2288
2300
  };
2289
2301
 
2290
2302
  // lib/createCopperShapesForLayer.ts
2291
- import { Polygon as Polygon4, Box as Box2, BooleanOperations } from "@flatten-js/core";
2292
- import { ShapePath as ShapePath25 } from "lbrnts";
2303
+ import { Polygon as Polygon3, Box as Box2, BooleanOperations } from "@flatten-js/core";
2304
+ import { ShapePath as ShapePath26 } from "lbrnts";
2293
2305
  var outputPolygon = (poly, cutIndex, project) => {
2294
2306
  if (poly.faces.size > 1) {
2295
2307
  for (const face of poly.faces) {
@@ -2298,11 +2310,11 @@ var outputPolygon = (poly, cutIndex, project) => {
2298
2310
  facePoints.push(edge.start);
2299
2311
  }
2300
2312
  if (facePoints.length >= 3) {
2301
- const facePoly = new Polygon4(facePoints);
2313
+ const facePoly = new Polygon3(facePoints);
2302
2314
  const { verts: verts2, prims: prims2 } = polygonToShapePathData(facePoly);
2303
2315
  if (verts2.length > 0) {
2304
2316
  project.children.push(
2305
- new ShapePath25({
2317
+ new ShapePath26({
2306
2318
  cutIndex,
2307
2319
  verts: verts2,
2308
2320
  prims: prims2,
@@ -2316,7 +2328,7 @@ var outputPolygon = (poly, cutIndex, project) => {
2316
2328
  }
2317
2329
  const { verts, prims } = polygonToShapePathData(poly);
2318
2330
  project.children.push(
2319
- new ShapePath25({
2331
+ new ShapePath26({
2320
2332
  cutIndex,
2321
2333
  verts,
2322
2334
  prims,
@@ -2326,7 +2338,7 @@ var outputPolygon = (poly, cutIndex, project) => {
2326
2338
  };
2327
2339
  var outputIndividualGeometries = (netGeoms, cutIndex, project) => {
2328
2340
  for (const geom of netGeoms) {
2329
- const poly = geom instanceof Box2 ? new Polygon4(geom) : geom;
2341
+ const poly = geom instanceof Box2 ? new Polygon3(geom) : geom;
2330
2342
  outputPolygon(poly, cutIndex, project);
2331
2343
  }
2332
2344
  };
@@ -2355,18 +2367,18 @@ var createCopperShapesForLayer = ({
2355
2367
  }
2356
2368
  if (netGeoms.length === 1) {
2357
2369
  const geom = netGeoms[0];
2358
- const poly = geom instanceof Box2 ? new Polygon4(geom) : geom;
2370
+ const poly = geom instanceof Box2 ? new Polygon3(geom) : geom;
2359
2371
  outputPolygon(poly, cutIndex, project);
2360
2372
  continue;
2361
2373
  }
2362
2374
  try {
2363
2375
  let union = netGeoms[0];
2364
2376
  if (union instanceof Box2) {
2365
- union = new Polygon4(union);
2377
+ union = new Polygon3(union);
2366
2378
  }
2367
2379
  let unionFailed = false;
2368
2380
  for (const geom of netGeoms.slice(1)) {
2369
- const poly = geom instanceof Polygon4 ? geom : new Polygon4(geom);
2381
+ const poly = geom instanceof Polygon3 ? geom : new Polygon3(geom);
2370
2382
  union = BooleanOperations.unify(union, poly);
2371
2383
  if (union.faces.size === 0) {
2372
2384
  unionFailed = true;
@@ -2396,8 +2408,8 @@ var createCopperShapesForLayer = ({
2396
2408
  };
2397
2409
 
2398
2410
  // lib/createTraceClearanceAreasForLayer.ts
2399
- import { Polygon as Polygon5, Box as Box3, BooleanOperations as BooleanOperations2 } from "@flatten-js/core";
2400
- import { ShapePath as ShapePath26 } from "lbrnts";
2411
+ import { Polygon as Polygon4, Box as Box3, BooleanOperations as BooleanOperations2 } from "@flatten-js/core";
2412
+ import { ShapePath as ShapePath27 } from "lbrnts";
2401
2413
  var createTraceClearanceAreasForLayer = ({
2402
2414
  layer,
2403
2415
  ctx
@@ -2427,31 +2439,31 @@ var createTraceClearanceAreasForLayer = ({
2427
2439
  try {
2428
2440
  let innerUnion = innerGeoms[0];
2429
2441
  if (innerUnion instanceof Box3) {
2430
- innerUnion = new Polygon5(innerUnion);
2442
+ innerUnion = new Polygon4(innerUnion);
2431
2443
  }
2432
2444
  for (const geom of innerGeoms.slice(1)) {
2433
- if (geom instanceof Polygon5) {
2445
+ if (geom instanceof Polygon4) {
2434
2446
  innerUnion = BooleanOperations2.unify(innerUnion, geom);
2435
2447
  } else if (geom instanceof Box3) {
2436
- innerUnion = BooleanOperations2.unify(innerUnion, new Polygon5(geom));
2448
+ innerUnion = BooleanOperations2.unify(innerUnion, new Polygon4(geom));
2437
2449
  }
2438
2450
  }
2439
2451
  let outerUnion = outerGeoms[0];
2440
2452
  if (outerUnion instanceof Box3) {
2441
- outerUnion = new Polygon5(outerUnion);
2453
+ outerUnion = new Polygon4(outerUnion);
2442
2454
  }
2443
2455
  for (const geom of outerGeoms.slice(1)) {
2444
- if (geom instanceof Polygon5) {
2456
+ if (geom instanceof Polygon4) {
2445
2457
  outerUnion = BooleanOperations2.unify(outerUnion, geom);
2446
2458
  } else if (geom instanceof Box3) {
2447
- outerUnion = BooleanOperations2.unify(outerUnion, new Polygon5(geom));
2459
+ outerUnion = BooleanOperations2.unify(outerUnion, new Polygon4(geom));
2448
2460
  }
2449
2461
  }
2450
2462
  const clearanceArea = BooleanOperations2.subtract(outerUnion, innerUnion);
2451
2463
  for (const island of clearanceArea.splitToIslands()) {
2452
2464
  const { verts, prims } = polygonToShapePathData(island);
2453
2465
  project.children.push(
2454
- new ShapePath26({
2466
+ new ShapePath27({
2455
2467
  cutIndex: cutSetting.index,
2456
2468
  verts,
2457
2469
  prims,
@@ -2482,6 +2494,7 @@ var convertCircuitJsonToLbrn = (circuitJson, options = {}) => {
2482
2494
  const includeCopper = options.includeCopper ?? true;
2483
2495
  const includeSoldermask = options.includeSoldermask ?? false;
2484
2496
  const globalCopperSoldermaskMarginAdjustment = options.globalCopperSoldermaskMarginAdjustment ?? 0;
2497
+ const solderMaskMarginPercent = options.solderMaskMarginPercent ?? 0;
2485
2498
  const laserProfile = options.laserProfile;
2486
2499
  const defaultCopperSettings = {
2487
2500
  speed: 300,
@@ -2598,7 +2611,8 @@ var convertCircuitJsonToLbrn = (circuitJson, options = {}) => {
2598
2611
  traceMargin,
2599
2612
  laserSpotSize,
2600
2613
  topTraceClearanceAreaCutSetting,
2601
- bottomTraceClearanceAreaCutSetting
2614
+ bottomTraceClearanceAreaCutSetting,
2615
+ solderMaskMarginPercent
2602
2616
  };
2603
2617
  for (const net of Object.keys(connMap.netMap)) {
2604
2618
  ctx.topCutNetGeoms.set(net, []);