circuit-json-to-gerber 0.0.75 → 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,14 +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;
|
|
2748
|
-
const
|
|
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) => ({
|
|
2749
2833
|
x: point.x + element.x,
|
|
2750
2834
|
y: point.y + element.y
|
|
2751
2835
|
}));
|
|
2752
2836
|
addClosedRegionFromPoints({
|
|
2753
2837
|
target: glayer,
|
|
2754
2838
|
apertureSource: glayer,
|
|
2755
|
-
points:
|
|
2839
|
+
points: translatedPoints
|
|
2756
2840
|
});
|
|
2757
2841
|
continue;
|
|
2758
2842
|
}
|
|
@@ -2774,10 +2858,17 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2774
2858
|
padHeightCandidates.push(element.rect_pad_height);
|
|
2775
2859
|
}
|
|
2776
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;
|
|
2777
2868
|
if (element.shape === "pill") {
|
|
2778
2869
|
const circleApertureConfig = {
|
|
2779
2870
|
standard_template_code: "C",
|
|
2780
|
-
diameter: Math.min(
|
|
2871
|
+
diameter: Math.min(aperturePadW, aperturePadH)
|
|
2781
2872
|
};
|
|
2782
2873
|
let aperture_number;
|
|
2783
2874
|
try {
|
|
@@ -2811,8 +2902,8 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2811
2902
|
y: element.y + rotatedY
|
|
2812
2903
|
};
|
|
2813
2904
|
};
|
|
2814
|
-
const isHorizontal =
|
|
2815
|
-
const offset = isHorizontal ? (
|
|
2905
|
+
const isHorizontal = aperturePadW >= aperturePadH;
|
|
2906
|
+
const offset = isHorizontal ? (aperturePadW - aperturePadH) / 2 : (aperturePadH - aperturePadW) / 2;
|
|
2816
2907
|
if (offset <= 0) {
|
|
2817
2908
|
const center = rotateAndTranslate(0, 0);
|
|
2818
2909
|
gb.add("flash_operation", { x: center.x, y: mfy(center.y) });
|
|
@@ -2843,7 +2934,6 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2843
2934
|
}
|
|
2844
2935
|
glayer.push(...gb.build());
|
|
2845
2936
|
} else {
|
|
2846
|
-
const soldermaskGlayer = glayers[getGerberLayerName(layer, "soldermask")];
|
|
2847
2937
|
let apertureConfig = getApertureConfigFromPcbPlatedHole({
|
|
2848
2938
|
...element,
|
|
2849
2939
|
...element.shape !== "circle" ? { outer_width: padW, outer_height: padH } : {}
|
|
@@ -3135,4 +3225,4 @@ export {
|
|
|
3135
3225
|
stringifyGerberCommands,
|
|
3136
3226
|
convertSoupToGerberCommands
|
|
3137
3227
|
};
|
|
3138
|
-
//# sourceMappingURL=chunk-
|
|
3228
|
+
//# sourceMappingURL=chunk-ER5XAENM.js.map
|