circuit-json-to-gerber 0.0.74 → 0.0.76
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.
|
@@ -1892,7 +1892,7 @@ var findApertureNumber = (glayer, search_params) => {
|
|
|
1892
1892
|
// package.json
|
|
1893
1893
|
var package_default = {
|
|
1894
1894
|
name: "circuit-json-to-gerber",
|
|
1895
|
-
version: "0.0.
|
|
1895
|
+
version: "0.0.75",
|
|
1896
1896
|
main: "dist/index.js",
|
|
1897
1897
|
type: "module",
|
|
1898
1898
|
scripts: {
|
|
@@ -2021,6 +2021,82 @@ var getGerberLayerName = (layer_ref, layer_type) => {
|
|
|
2021
2021
|
return `${layerRefToGerberPrefix[layer_ref]}${layerTypeToGerberSuffix[layer_type]}`;
|
|
2022
2022
|
};
|
|
2023
2023
|
|
|
2024
|
+
// src/gerber/convert-soup-to-gerber-commands/offsetPolygonOutline.ts
|
|
2025
|
+
var getSignedPolygonArea = (points) => {
|
|
2026
|
+
let area = 0;
|
|
2027
|
+
for (let i = 0; i < points.length; i++) {
|
|
2028
|
+
const current = points[i];
|
|
2029
|
+
const next = points[(i + 1) % points.length];
|
|
2030
|
+
area += current.x * next.y - next.x * current.y;
|
|
2031
|
+
}
|
|
2032
|
+
return area / 2;
|
|
2033
|
+
};
|
|
2034
|
+
var getLineIntersection = (lineA, lineB) => {
|
|
2035
|
+
const ax = lineA.end.x - lineA.start.x;
|
|
2036
|
+
const ay = lineA.end.y - lineA.start.y;
|
|
2037
|
+
const bx = lineB.end.x - lineB.start.x;
|
|
2038
|
+
const by = lineB.end.y - lineB.start.y;
|
|
2039
|
+
const denominator = ax * by - ay * bx;
|
|
2040
|
+
if (Math.abs(denominator) < 1e-9) {
|
|
2041
|
+
return null;
|
|
2042
|
+
}
|
|
2043
|
+
const cx = lineB.start.x - lineA.start.x;
|
|
2044
|
+
const cy = lineB.start.y - lineA.start.y;
|
|
2045
|
+
const t = (cx * by - cy * bx) / denominator;
|
|
2046
|
+
return {
|
|
2047
|
+
x: lineA.start.x + ax * t,
|
|
2048
|
+
y: lineA.start.y + ay * t
|
|
2049
|
+
};
|
|
2050
|
+
};
|
|
2051
|
+
var offsetPolygonOutline = (points, offset) => {
|
|
2052
|
+
if (points.length < 3 || offset === 0) {
|
|
2053
|
+
return points;
|
|
2054
|
+
}
|
|
2055
|
+
const isCounterClockwise = getSignedPolygonArea(points) > 0;
|
|
2056
|
+
const shiftedEdges = [];
|
|
2057
|
+
for (let i = 0; i < points.length; i++) {
|
|
2058
|
+
const start = points[i];
|
|
2059
|
+
const end = points[(i + 1) % points.length];
|
|
2060
|
+
const dx = end.x - start.x;
|
|
2061
|
+
const dy = end.y - start.y;
|
|
2062
|
+
const length = Math.sqrt(dx * dx + dy * dy);
|
|
2063
|
+
if (length < 1e-9) {
|
|
2064
|
+
continue;
|
|
2065
|
+
}
|
|
2066
|
+
let normalX = -dy / length;
|
|
2067
|
+
let normalY = dx / length;
|
|
2068
|
+
if (isCounterClockwise) {
|
|
2069
|
+
normalX = dy / length;
|
|
2070
|
+
normalY = -dx / length;
|
|
2071
|
+
}
|
|
2072
|
+
shiftedEdges.push({
|
|
2073
|
+
start: {
|
|
2074
|
+
x: start.x + normalX * offset,
|
|
2075
|
+
y: start.y + normalY * offset
|
|
2076
|
+
},
|
|
2077
|
+
end: {
|
|
2078
|
+
x: end.x + normalX * offset,
|
|
2079
|
+
y: end.y + normalY * offset
|
|
2080
|
+
}
|
|
2081
|
+
});
|
|
2082
|
+
}
|
|
2083
|
+
if (shiftedEdges.length < 3) {
|
|
2084
|
+
return points;
|
|
2085
|
+
}
|
|
2086
|
+
const offsetPoints = [];
|
|
2087
|
+
for (let i = 0; i < shiftedEdges.length; i++) {
|
|
2088
|
+
const previousEdge = shiftedEdges[(i - 1 + shiftedEdges.length) % shiftedEdges.length];
|
|
2089
|
+
const currentEdge = shiftedEdges[i];
|
|
2090
|
+
const intersection = getLineIntersection(previousEdge, currentEdge);
|
|
2091
|
+
if (intersection) {
|
|
2092
|
+
offsetPoints.push(intersection);
|
|
2093
|
+
} else {
|
|
2094
|
+
offsetPoints.push(currentEdge.start);
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
return offsetPoints;
|
|
2098
|
+
};
|
|
2099
|
+
|
|
2024
2100
|
// src/gerber/convert-soup-to-gerber-commands/index.ts
|
|
2025
2101
|
import { lineAlphabet } from "@tscircuit/alphabet";
|
|
2026
2102
|
import {
|
|
@@ -2745,10 +2821,22 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2745
2821
|
if (element.shape === "hole_with_polygon_pad") {
|
|
2746
2822
|
const { pad_outline } = element;
|
|
2747
2823
|
if (!pad_outline?.length) continue;
|
|
2824
|
+
const soldermaskGlayer2 = glayers[getGerberLayerName(layer, "soldermask")];
|
|
2825
|
+
let points = pad_outline;
|
|
2826
|
+
if (glayer === soldermaskGlayer2 && "soldermask_margin" in element && typeof element.soldermask_margin === "number") {
|
|
2827
|
+
points = offsetPolygonOutline(
|
|
2828
|
+
pad_outline,
|
|
2829
|
+
element.soldermask_margin
|
|
2830
|
+
);
|
|
2831
|
+
}
|
|
2832
|
+
const translatedPoints = points.map((point) => ({
|
|
2833
|
+
x: point.x + element.x,
|
|
2834
|
+
y: point.y + element.y
|
|
2835
|
+
}));
|
|
2748
2836
|
addClosedRegionFromPoints({
|
|
2749
2837
|
target: glayer,
|
|
2750
2838
|
apertureSource: glayer,
|
|
2751
|
-
points:
|
|
2839
|
+
points: translatedPoints
|
|
2752
2840
|
});
|
|
2753
2841
|
continue;
|
|
2754
2842
|
}
|
|
@@ -2770,10 +2858,17 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2770
2858
|
padHeightCandidates.push(element.rect_pad_height);
|
|
2771
2859
|
}
|
|
2772
2860
|
const padH = Math.max(...padHeightCandidates);
|
|
2861
|
+
const soldermaskGlayer = glayers[getGerberLayerName(layer, "soldermask")];
|
|
2862
|
+
let soldermaskMargin = 0;
|
|
2863
|
+
if (glayer === soldermaskGlayer && "soldermask_margin" in element && typeof element.soldermask_margin === "number") {
|
|
2864
|
+
soldermaskMargin = element.soldermask_margin;
|
|
2865
|
+
}
|
|
2866
|
+
const aperturePadW = padW + soldermaskMargin * 2;
|
|
2867
|
+
const aperturePadH = padH + soldermaskMargin * 2;
|
|
2773
2868
|
if (element.shape === "pill") {
|
|
2774
2869
|
const circleApertureConfig = {
|
|
2775
2870
|
standard_template_code: "C",
|
|
2776
|
-
diameter: Math.min(
|
|
2871
|
+
diameter: Math.min(aperturePadW, aperturePadH)
|
|
2777
2872
|
};
|
|
2778
2873
|
let aperture_number;
|
|
2779
2874
|
try {
|
|
@@ -2807,8 +2902,8 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2807
2902
|
y: element.y + rotatedY
|
|
2808
2903
|
};
|
|
2809
2904
|
};
|
|
2810
|
-
const isHorizontal =
|
|
2811
|
-
const offset = isHorizontal ? (
|
|
2905
|
+
const isHorizontal = aperturePadW >= aperturePadH;
|
|
2906
|
+
const offset = isHorizontal ? (aperturePadW - aperturePadH) / 2 : (aperturePadH - aperturePadW) / 2;
|
|
2812
2907
|
if (offset <= 0) {
|
|
2813
2908
|
const center = rotateAndTranslate(0, 0);
|
|
2814
2909
|
gb.add("flash_operation", { x: center.x, y: mfy(center.y) });
|
|
@@ -2839,7 +2934,6 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2839
2934
|
}
|
|
2840
2935
|
glayer.push(...gb.build());
|
|
2841
2936
|
} else {
|
|
2842
|
-
const soldermaskGlayer = glayers[getGerberLayerName(layer, "soldermask")];
|
|
2843
2937
|
let apertureConfig = getApertureConfigFromPcbPlatedHole({
|
|
2844
2938
|
...element,
|
|
2845
2939
|
...element.shape !== "circle" ? { outer_width: padW, outer_height: padH } : {}
|
|
@@ -3131,4 +3225,4 @@ export {
|
|
|
3131
3225
|
stringifyGerberCommands,
|
|
3132
3226
|
convertSoupToGerberCommands
|
|
3133
3227
|
};
|
|
3134
|
-
//# sourceMappingURL=chunk-
|
|
3228
|
+
//# sourceMappingURL=chunk-ER5XAENM.js.map
|