circuit-json-to-gerber 0.0.68 → 0.0.70
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.
|
@@ -1112,7 +1112,17 @@ var define_aperture_template = defineGerberCommand({
|
|
|
1112
1112
|
if (macro_name === "HORZPILL" || macro_name === "VERTPILL") {
|
|
1113
1113
|
commandString += `${props.x_size.toFixed(6)}X${props.y_size.toFixed(6)}X${props.circle_diameter.toFixed(6)}X${props.circle_center_offset.toFixed(6)}`;
|
|
1114
1114
|
} else if (macro_name === "ROUNDRECT") {
|
|
1115
|
-
|
|
1115
|
+
commandString += [
|
|
1116
|
+
props.corner_radius,
|
|
1117
|
+
props.corner_1_x,
|
|
1118
|
+
props.corner_1_y,
|
|
1119
|
+
props.corner_2_x,
|
|
1120
|
+
props.corner_2_y,
|
|
1121
|
+
props.corner_3_x,
|
|
1122
|
+
props.corner_3_y,
|
|
1123
|
+
props.corner_4_x,
|
|
1124
|
+
props.corner_4_y
|
|
1125
|
+
].map((value) => value.toFixed(6)).join("X");
|
|
1116
1126
|
}
|
|
1117
1127
|
commandString += "*%";
|
|
1118
1128
|
return commandString;
|
|
@@ -1289,7 +1299,7 @@ var defineCommonMacros = (glayer) => {
|
|
|
1289
1299
|
1,1,$3,0.0,$4*
|
|
1290
1300
|
`.trim()
|
|
1291
1301
|
}).add("define_macro_aperture_template", {
|
|
1292
|
-
macro_name: "
|
|
1302
|
+
macro_name: "ROUNDRECT",
|
|
1293
1303
|
template_code: `
|
|
1294
1304
|
0 Rectangle with rounded corners*
|
|
1295
1305
|
0 $1 Corner radius*
|
|
@@ -1355,6 +1365,26 @@ var getLayerRefFromGerberLayerName = (glayer_name) => {
|
|
|
1355
1365
|
if (innerLayerMatch) return `inner${innerLayerMatch[1]}`;
|
|
1356
1366
|
throw new Error(`Could not infer layer ref from ${glayer_name}`);
|
|
1357
1367
|
};
|
|
1368
|
+
var getClampedRoundedRectCornerRadius = (width, height, cornerRadius) => {
|
|
1369
|
+
if (typeof cornerRadius !== "number") return 0;
|
|
1370
|
+
return Math.max(0, Math.min(cornerRadius, width / 2, height / 2));
|
|
1371
|
+
};
|
|
1372
|
+
var getRoundedRectApertureConfig = (width, height, cornerRadius) => {
|
|
1373
|
+
const halfWidth = width / 2;
|
|
1374
|
+
const halfHeight = height / 2;
|
|
1375
|
+
return {
|
|
1376
|
+
macro_name: "ROUNDRECT",
|
|
1377
|
+
corner_radius: cornerRadius,
|
|
1378
|
+
corner_1_x: -halfWidth + cornerRadius,
|
|
1379
|
+
corner_1_y: halfHeight - cornerRadius,
|
|
1380
|
+
corner_2_x: halfWidth - cornerRadius,
|
|
1381
|
+
corner_2_y: halfHeight - cornerRadius,
|
|
1382
|
+
corner_3_x: halfWidth - cornerRadius,
|
|
1383
|
+
corner_3_y: -halfHeight + cornerRadius,
|
|
1384
|
+
corner_4_x: -halfWidth + cornerRadius,
|
|
1385
|
+
corner_4_y: -halfHeight + cornerRadius
|
|
1386
|
+
};
|
|
1387
|
+
};
|
|
1358
1388
|
function defineAperturesForLayer({
|
|
1359
1389
|
glayer,
|
|
1360
1390
|
circuitJson,
|
|
@@ -1403,7 +1433,21 @@ function defineAperturesForLayer({
|
|
|
1403
1433
|
...gerberBuilder().add("delete_attribute", {}).add("comment", { comment: "aperture END LIST" }).build()
|
|
1404
1434
|
);
|
|
1405
1435
|
}
|
|
1436
|
+
var REGION_APERTURE_CONFIG = {
|
|
1437
|
+
standard_template_code: "C",
|
|
1438
|
+
diameter: 1e-3
|
|
1439
|
+
};
|
|
1406
1440
|
var getApertureConfigFromPcbSmtpad = (elm) => {
|
|
1441
|
+
if (elm.shape === "rect" || elm.shape === "rotated_rect") {
|
|
1442
|
+
const cornerRadius = getClampedRoundedRectCornerRadius(
|
|
1443
|
+
elm.width,
|
|
1444
|
+
elm.height,
|
|
1445
|
+
"corner_radius" in elm ? elm.corner_radius : void 0
|
|
1446
|
+
);
|
|
1447
|
+
if (cornerRadius > 0) {
|
|
1448
|
+
return getRoundedRectApertureConfig(elm.width, elm.height, cornerRadius);
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1407
1451
|
if (elm.shape === "rect") {
|
|
1408
1452
|
return {
|
|
1409
1453
|
standard_template_code: "R",
|
|
@@ -1457,6 +1501,18 @@ var getApertureConfigFromPcbSmtpadSoldermask = (elm) => {
|
|
|
1457
1501
|
if ("soldermask_margin" in elm && typeof elm.soldermask_margin === "number") {
|
|
1458
1502
|
soldermaskMargin = elm.soldermask_margin;
|
|
1459
1503
|
}
|
|
1504
|
+
if (elm.shape === "rect" || elm.shape === "rotated_rect") {
|
|
1505
|
+
const width = elm.width + soldermaskMargin * 2;
|
|
1506
|
+
const height = elm.height + soldermaskMargin * 2;
|
|
1507
|
+
const cornerRadius = getClampedRoundedRectCornerRadius(
|
|
1508
|
+
width,
|
|
1509
|
+
height,
|
|
1510
|
+
"corner_radius" in elm && typeof elm.corner_radius === "number" ? elm.corner_radius + soldermaskMargin : void 0
|
|
1511
|
+
);
|
|
1512
|
+
if (cornerRadius > 0) {
|
|
1513
|
+
return getRoundedRectApertureConfig(width, height, cornerRadius);
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1460
1516
|
if (elm.shape === "rect") {
|
|
1461
1517
|
return {
|
|
1462
1518
|
standard_template_code: "R",
|
|
@@ -1737,6 +1793,7 @@ function getAllApertureTemplateConfigsForLayer({
|
|
|
1737
1793
|
const configs = [];
|
|
1738
1794
|
const configHashMap = /* @__PURE__ */ new Set();
|
|
1739
1795
|
const isSoldermaskLayer = glayer_name.endsWith("_Mask");
|
|
1796
|
+
const isCopperLayer = glayer_name.endsWith("_Cu");
|
|
1740
1797
|
const addConfigIfNew = (config) => {
|
|
1741
1798
|
const hash = stableStringify(config);
|
|
1742
1799
|
if (!configHashMap.has(hash)) {
|
|
@@ -1768,6 +1825,9 @@ function getAllApertureTemplateConfigsForLayer({
|
|
|
1768
1825
|
}
|
|
1769
1826
|
} else if (elm.type === "pcb_plated_hole") {
|
|
1770
1827
|
if (elm.layers.includes(layer)) {
|
|
1828
|
+
if (elm.shape === "hole_with_polygon_pad") {
|
|
1829
|
+
continue;
|
|
1830
|
+
}
|
|
1771
1831
|
if (glayer_name.endsWith("_Mask") && elm.is_covered_with_solder_mask === true) {
|
|
1772
1832
|
continue;
|
|
1773
1833
|
}
|
|
@@ -1806,6 +1866,27 @@ function getAllApertureTemplateConfigsForLayer({
|
|
|
1806
1866
|
addConfigIfNew(getApertureConfigFromPcbCopperText(elm));
|
|
1807
1867
|
}
|
|
1808
1868
|
}
|
|
1869
|
+
const needsRegionAperture = circuitJson.some((elm) => {
|
|
1870
|
+
if (elm.type === "pcb_copper_pour") {
|
|
1871
|
+
if (elm.layer !== layer) return false;
|
|
1872
|
+
if (isCopperLayer) return true;
|
|
1873
|
+
return isSoldermaskLayer && elm.covered_with_solder_mask === false;
|
|
1874
|
+
}
|
|
1875
|
+
if (elm.type === "pcb_smtpad" && elm.shape === "polygon") {
|
|
1876
|
+
if (elm.layer !== layer) return false;
|
|
1877
|
+
if (isCopperLayer) return true;
|
|
1878
|
+
return isSoldermaskLayer && elm.is_covered_with_solder_mask !== true;
|
|
1879
|
+
}
|
|
1880
|
+
if (elm.type === "pcb_plated_hole" && elm.shape === "hole_with_polygon_pad") {
|
|
1881
|
+
if (!elm.layers.includes(layer)) return false;
|
|
1882
|
+
if (isCopperLayer) return true;
|
|
1883
|
+
return isSoldermaskLayer && elm.is_covered_with_solder_mask !== true;
|
|
1884
|
+
}
|
|
1885
|
+
return false;
|
|
1886
|
+
});
|
|
1887
|
+
if (needsRegionAperture) {
|
|
1888
|
+
addConfigIfNew(REGION_APERTURE_CONFIG);
|
|
1889
|
+
}
|
|
1809
1890
|
return configs;
|
|
1810
1891
|
}
|
|
1811
1892
|
|
|
@@ -1835,7 +1916,7 @@ var findApertureNumber = (glayer, search_params) => {
|
|
|
1835
1916
|
// package.json
|
|
1836
1917
|
var package_default = {
|
|
1837
1918
|
name: "circuit-json-to-gerber",
|
|
1838
|
-
version: "0.0.
|
|
1919
|
+
version: "0.0.68",
|
|
1839
1920
|
main: "dist/index.js",
|
|
1840
1921
|
type: "module",
|
|
1841
1922
|
scripts: {
|
|
@@ -2068,6 +2149,34 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2068
2149
|
}).build()
|
|
2069
2150
|
);
|
|
2070
2151
|
const mfy = (y) => opts.flip_y_axis ? -y : y;
|
|
2152
|
+
const getRegionApertureNumber = (glayer) => findApertureNumber(glayer, REGION_APERTURE_CONFIG);
|
|
2153
|
+
const addClosedRegionFromPoints = ({
|
|
2154
|
+
target,
|
|
2155
|
+
apertureSource,
|
|
2156
|
+
points
|
|
2157
|
+
}) => {
|
|
2158
|
+
if (points.length === 0) return;
|
|
2159
|
+
const regionApertureNumber = getRegionApertureNumber(apertureSource);
|
|
2160
|
+
const regionBuilder = gerberBuilder().add("select_aperture", {
|
|
2161
|
+
aperture_number: regionApertureNumber
|
|
2162
|
+
}).add("start_region_statement", {});
|
|
2163
|
+
regionBuilder.add("move_operation", {
|
|
2164
|
+
x: points[0].x,
|
|
2165
|
+
y: mfy(points[0].y)
|
|
2166
|
+
});
|
|
2167
|
+
for (let i = 1; i < points.length; i++) {
|
|
2168
|
+
regionBuilder.add("plot_operation", {
|
|
2169
|
+
x: points[i].x,
|
|
2170
|
+
y: mfy(points[i].y)
|
|
2171
|
+
});
|
|
2172
|
+
}
|
|
2173
|
+
regionBuilder.add("plot_operation", {
|
|
2174
|
+
x: points[0].x,
|
|
2175
|
+
y: mfy(points[0].y)
|
|
2176
|
+
});
|
|
2177
|
+
regionBuilder.add("end_region_statement", {});
|
|
2178
|
+
target.push(...regionBuilder.build());
|
|
2179
|
+
};
|
|
2071
2180
|
const renderVectorText = (element, layer, layerType, getApertureConfig) => {
|
|
2072
2181
|
if (element.layer !== layer) return;
|
|
2073
2182
|
const CAP_HEIGHT_SCALE = 0.7;
|
|
@@ -2308,7 +2417,8 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2308
2417
|
const { brep_shape } = element;
|
|
2309
2418
|
if (!brep_shape) continue;
|
|
2310
2419
|
const { outer_ring, inner_rings } = brep_shape;
|
|
2311
|
-
const
|
|
2420
|
+
const regionApertureNumber = getRegionApertureNumber(copper_glayer);
|
|
2421
|
+
const outer_builder = gerberBuilder().add("select_aperture", { aperture_number: regionApertureNumber }).add("start_region_statement", {});
|
|
2312
2422
|
drawRingToBuilder(outer_builder, reverseRing(outer_ring));
|
|
2313
2423
|
outer_builder.add("end_region_statement", {});
|
|
2314
2424
|
all_pour_commands.push(...outer_builder.build());
|
|
@@ -2317,7 +2427,9 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2317
2427
|
...gerberBuilder().add("set_layer_polarity", { polarity: "C" }).build()
|
|
2318
2428
|
);
|
|
2319
2429
|
for (const inner_ring of inner_rings) {
|
|
2320
|
-
const inner_builder = gerberBuilder().add("select_aperture", {
|
|
2430
|
+
const inner_builder = gerberBuilder().add("select_aperture", {
|
|
2431
|
+
aperture_number: regionApertureNumber
|
|
2432
|
+
}).add("start_region_statement", {});
|
|
2321
2433
|
drawRingToBuilder(inner_builder, inner_ring);
|
|
2322
2434
|
inner_builder.add("end_region_statement", {});
|
|
2323
2435
|
all_pour_commands.push(...inner_builder.build());
|
|
@@ -2352,7 +2464,8 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2352
2464
|
const transformedPoints = points.map(
|
|
2353
2465
|
(p) => applyToPoint(transformMatrix, p)
|
|
2354
2466
|
);
|
|
2355
|
-
const
|
|
2467
|
+
const regionApertureNumber = getRegionApertureNumber(copper_glayer);
|
|
2468
|
+
const rect_builder = gerberBuilder().add("select_aperture", { aperture_number: regionApertureNumber }).add("start_region_statement", {});
|
|
2356
2469
|
rect_builder.add("move_operation", {
|
|
2357
2470
|
x: transformedPoints[0].x,
|
|
2358
2471
|
y: mfy(transformedPoints[0].y)
|
|
@@ -2371,25 +2484,11 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2371
2484
|
all_pour_commands.push(...rect_builder.build());
|
|
2372
2485
|
} else if (element.shape === "polygon") {
|
|
2373
2486
|
const { points } = element;
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
});
|
|
2380
|
-
for (let i = 1; i < points.length; i++) {
|
|
2381
|
-
poly_builder.add("plot_operation", {
|
|
2382
|
-
x: points[i].x,
|
|
2383
|
-
y: mfy(points[i].y)
|
|
2384
|
-
});
|
|
2385
|
-
}
|
|
2386
|
-
poly_builder.add("plot_operation", {
|
|
2387
|
-
x: points[0].x,
|
|
2388
|
-
y: mfy(points[0].y)
|
|
2389
|
-
});
|
|
2390
|
-
poly_builder.add("end_region_statement", {});
|
|
2391
|
-
all_pour_commands.push(...poly_builder.build());
|
|
2392
|
-
}
|
|
2487
|
+
addClosedRegionFromPoints({
|
|
2488
|
+
target: all_pour_commands,
|
|
2489
|
+
apertureSource: copper_glayer,
|
|
2490
|
+
points
|
|
2491
|
+
});
|
|
2393
2492
|
}
|
|
2394
2493
|
copper_glayer.push(...all_pour_commands);
|
|
2395
2494
|
if (element.covered_with_solder_mask === false) {
|
|
@@ -2540,26 +2639,13 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2540
2639
|
);
|
|
2541
2640
|
}
|
|
2542
2641
|
for (const glayer of layers_to_add_to) {
|
|
2543
|
-
const pad_builder = gerberBuilder().add("select_aperture", { aperture_number: 10 }).add("start_region_statement", {});
|
|
2544
2642
|
const { points } = element;
|
|
2545
|
-
if (points
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
pad_builder.add("plot_operation", {
|
|
2552
|
-
x: points[i].x,
|
|
2553
|
-
y: mfy(points[i].y)
|
|
2554
|
-
});
|
|
2555
|
-
}
|
|
2556
|
-
pad_builder.add("plot_operation", {
|
|
2557
|
-
x: points[0].x,
|
|
2558
|
-
y: mfy(points[0].y)
|
|
2559
|
-
});
|
|
2560
|
-
}
|
|
2561
|
-
pad_builder.add("end_region_statement", {});
|
|
2562
|
-
glayer.push(...pad_builder.build());
|
|
2643
|
+
if (!points) continue;
|
|
2644
|
+
addClosedRegionFromPoints({
|
|
2645
|
+
target: glayer,
|
|
2646
|
+
apertureSource: glayer,
|
|
2647
|
+
points
|
|
2648
|
+
});
|
|
2563
2649
|
}
|
|
2564
2650
|
}
|
|
2565
2651
|
} else if (element.type === "pcb_solder_paste") {
|
|
@@ -2609,6 +2695,16 @@ var convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
|
2609
2695
|
layersToAddTo.push(glayers[getGerberLayerName(layer, "soldermask")]);
|
|
2610
2696
|
}
|
|
2611
2697
|
for (const glayer of layersToAddTo) {
|
|
2698
|
+
if (element.shape === "hole_with_polygon_pad") {
|
|
2699
|
+
const { pad_outline } = element;
|
|
2700
|
+
if (!pad_outline?.length) continue;
|
|
2701
|
+
addClosedRegionFromPoints({
|
|
2702
|
+
target: glayer,
|
|
2703
|
+
apertureSource: glayer,
|
|
2704
|
+
points: pad_outline
|
|
2705
|
+
});
|
|
2706
|
+
continue;
|
|
2707
|
+
}
|
|
2612
2708
|
const holeW = "hole_width" in element && typeof element.hole_width === "number" ? element.hole_width : 0;
|
|
2613
2709
|
const holeH = "hole_height" in element && typeof element.hole_height === "number" ? element.hole_height : 0;
|
|
2614
2710
|
const padWidthCandidates = [holeW];
|
|
@@ -2988,4 +3084,4 @@ export {
|
|
|
2988
3084
|
stringifyGerberCommands,
|
|
2989
3085
|
convertSoupToGerberCommands
|
|
2990
3086
|
};
|
|
2991
|
-
//# sourceMappingURL=chunk-
|
|
3087
|
+
//# sourceMappingURL=chunk-ISNPG4RS.js.map
|