circuit-json-to-gerber 0.0.47 → 0.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-LRAY3J4M.js → chunk-VM5XFQ53.js} +175 -160
- package/dist/chunk-VM5XFQ53.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-LRAY3J4M.js.map +0 -1
|
@@ -1422,7 +1422,7 @@ var findApertureNumber = (glayer, search_params) => {
|
|
|
1422
1422
|
// package.json
|
|
1423
1423
|
var package_default = {
|
|
1424
1424
|
name: "circuit-json-to-gerber",
|
|
1425
|
-
version: "0.0.
|
|
1425
|
+
version: "0.0.47",
|
|
1426
1426
|
main: "dist/index.js",
|
|
1427
1427
|
type: "module",
|
|
1428
1428
|
scripts: {
|
|
@@ -1772,6 +1772,179 @@ var convertSoupToGerberCommands = (soup, opts = {}) => {
|
|
|
1772
1772
|
);
|
|
1773
1773
|
}
|
|
1774
1774
|
};
|
|
1775
|
+
const drawRingToBuilder = (builder, ring) => {
|
|
1776
|
+
if (!ring || ring.vertices.length === 0) return;
|
|
1777
|
+
builder.add("move_operation", {
|
|
1778
|
+
x: ring.vertices[0].x,
|
|
1779
|
+
y: mfy(ring.vertices[0].y)
|
|
1780
|
+
});
|
|
1781
|
+
const vertices_loop = [...ring.vertices, ring.vertices[0]];
|
|
1782
|
+
for (let i = 0; i < vertices_loop.length - 1; i++) {
|
|
1783
|
+
const start = vertices_loop[i];
|
|
1784
|
+
const end = vertices_loop[i + 1];
|
|
1785
|
+
if (start.bulge && Math.abs(start.bulge) > 1e-9) {
|
|
1786
|
+
const bulge = (opts.flip_y_axis ? -1 : 1) * start.bulge;
|
|
1787
|
+
if (bulge > 0) {
|
|
1788
|
+
builder.add("set_movement_mode_to_counterclockwise_circular", {});
|
|
1789
|
+
} else {
|
|
1790
|
+
builder.add("set_movement_mode_to_clockwise_circular", {});
|
|
1791
|
+
}
|
|
1792
|
+
const p1 = { x: start.x, y: start.y };
|
|
1793
|
+
const p2 = { x: end.x, y: end.y };
|
|
1794
|
+
const dx = p2.x - p1.x;
|
|
1795
|
+
const dy = p2.y - p1.y;
|
|
1796
|
+
const d = Math.sqrt(dx * dx + dy * dy);
|
|
1797
|
+
if (d < 1e-9) {
|
|
1798
|
+
builder.add("set_movement_mode_to_linear", {});
|
|
1799
|
+
builder.add("plot_operation", {
|
|
1800
|
+
x: end.x,
|
|
1801
|
+
y: mfy(end.y)
|
|
1802
|
+
});
|
|
1803
|
+
continue;
|
|
1804
|
+
}
|
|
1805
|
+
const abs_b = Math.abs(bulge);
|
|
1806
|
+
const theta = 4 * Math.atan(abs_b);
|
|
1807
|
+
if (Math.abs(Math.sin(theta / 2)) < 1e-9) {
|
|
1808
|
+
builder.add("set_movement_mode_to_linear", {});
|
|
1809
|
+
builder.add("plot_operation", {
|
|
1810
|
+
x: end.x,
|
|
1811
|
+
y: mfy(end.y)
|
|
1812
|
+
});
|
|
1813
|
+
continue;
|
|
1814
|
+
}
|
|
1815
|
+
const R = d / (2 * Math.sin(theta / 2));
|
|
1816
|
+
const alpha = (Math.PI - theta) / 2;
|
|
1817
|
+
const phi = Math.atan2(dy, dx);
|
|
1818
|
+
const delta_angle = bulge > 0 ? alpha : -alpha;
|
|
1819
|
+
const angle_p1_center = phi + delta_angle;
|
|
1820
|
+
const Cx = p1.x + R * Math.cos(angle_p1_center);
|
|
1821
|
+
const Cy = p1.y + R * Math.sin(angle_p1_center);
|
|
1822
|
+
const i_offset = Cx - p1.x;
|
|
1823
|
+
const j_offset = Cy - p1.y;
|
|
1824
|
+
builder.add("plot_operation", {
|
|
1825
|
+
x: end.x,
|
|
1826
|
+
y: mfy(end.y),
|
|
1827
|
+
i: i_offset,
|
|
1828
|
+
j: opts.flip_y_axis ? -j_offset : j_offset
|
|
1829
|
+
});
|
|
1830
|
+
} else {
|
|
1831
|
+
builder.add("set_movement_mode_to_linear", {});
|
|
1832
|
+
builder.add("plot_operation", { x: end.x, y: mfy(end.y) });
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
};
|
|
1836
|
+
const reverseRing = (ring) => {
|
|
1837
|
+
const { vertices } = ring;
|
|
1838
|
+
if (!vertices || vertices.length === 0) return { vertices: [] };
|
|
1839
|
+
const n = vertices.length;
|
|
1840
|
+
const reversed_pts = [...vertices].reverse();
|
|
1841
|
+
const new_vertices = reversed_pts.map((pt, i) => {
|
|
1842
|
+
const bulge_v_idx = (n - 2 - i + n) % n;
|
|
1843
|
+
const bulge = vertices[bulge_v_idx].bulge;
|
|
1844
|
+
return { ...pt, bulge: bulge ? -bulge : void 0 };
|
|
1845
|
+
});
|
|
1846
|
+
return { vertices: new_vertices };
|
|
1847
|
+
};
|
|
1848
|
+
for (const layer of ["top", "bottom"]) {
|
|
1849
|
+
for (const element of soup) {
|
|
1850
|
+
if (element.type === "pcb_copper_pour" && layer === element.layer) {
|
|
1851
|
+
const copper_glayer = glayers[getGerberLayerName(layer, "copper")];
|
|
1852
|
+
const all_pour_commands = [];
|
|
1853
|
+
if (element.shape === "brep") {
|
|
1854
|
+
const { brep_shape } = element;
|
|
1855
|
+
if (!brep_shape) continue;
|
|
1856
|
+
const { outer_ring, inner_rings } = brep_shape;
|
|
1857
|
+
const outer_builder = gerberBuilder().add("select_aperture", { aperture_number: 10 }).add("start_region_statement", {});
|
|
1858
|
+
drawRingToBuilder(outer_builder, reverseRing(outer_ring));
|
|
1859
|
+
outer_builder.add("end_region_statement", {});
|
|
1860
|
+
all_pour_commands.push(...outer_builder.build());
|
|
1861
|
+
if (inner_rings && inner_rings.length > 0) {
|
|
1862
|
+
all_pour_commands.push(
|
|
1863
|
+
...gerberBuilder().add("set_layer_polarity", { polarity: "C" }).build()
|
|
1864
|
+
);
|
|
1865
|
+
for (const inner_ring of inner_rings) {
|
|
1866
|
+
const inner_builder = gerberBuilder().add("select_aperture", { aperture_number: 10 }).add("start_region_statement", {});
|
|
1867
|
+
drawRingToBuilder(inner_builder, inner_ring);
|
|
1868
|
+
inner_builder.add("end_region_statement", {});
|
|
1869
|
+
all_pour_commands.push(...inner_builder.build());
|
|
1870
|
+
}
|
|
1871
|
+
all_pour_commands.push(
|
|
1872
|
+
...gerberBuilder().add("set_layer_polarity", { polarity: "D" }).build()
|
|
1873
|
+
);
|
|
1874
|
+
}
|
|
1875
|
+
} else if (element.shape === "rect") {
|
|
1876
|
+
const { center, width, height, rotation } = element;
|
|
1877
|
+
const w = width / 2;
|
|
1878
|
+
const h = height / 2;
|
|
1879
|
+
const points = [
|
|
1880
|
+
{ x: -w, y: h },
|
|
1881
|
+
// Top-left
|
|
1882
|
+
{ x: w, y: h },
|
|
1883
|
+
// Top-right
|
|
1884
|
+
{ x: w, y: -h },
|
|
1885
|
+
// Bottom-right
|
|
1886
|
+
{ x: -w, y: -h }
|
|
1887
|
+
// Bottom-left
|
|
1888
|
+
];
|
|
1889
|
+
let transformMatrix = identity();
|
|
1890
|
+
if (rotation) {
|
|
1891
|
+
const angle_rad = rotation * Math.PI / 180;
|
|
1892
|
+
transformMatrix = rotate(angle_rad);
|
|
1893
|
+
}
|
|
1894
|
+
transformMatrix = compose(
|
|
1895
|
+
translate(center.x, center.y),
|
|
1896
|
+
transformMatrix
|
|
1897
|
+
);
|
|
1898
|
+
const transformedPoints = points.map(
|
|
1899
|
+
(p) => applyToPoint(transformMatrix, p)
|
|
1900
|
+
);
|
|
1901
|
+
const rect_builder = gerberBuilder().add("select_aperture", { aperture_number: 10 }).add("start_region_statement", {});
|
|
1902
|
+
rect_builder.add("move_operation", {
|
|
1903
|
+
x: transformedPoints[0].x,
|
|
1904
|
+
y: mfy(transformedPoints[0].y)
|
|
1905
|
+
});
|
|
1906
|
+
for (let i = 1; i < transformedPoints.length; i++) {
|
|
1907
|
+
rect_builder.add("plot_operation", {
|
|
1908
|
+
x: transformedPoints[i].x,
|
|
1909
|
+
y: mfy(transformedPoints[i].y)
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1912
|
+
rect_builder.add("plot_operation", {
|
|
1913
|
+
x: transformedPoints[0].x,
|
|
1914
|
+
y: mfy(transformedPoints[0].y)
|
|
1915
|
+
});
|
|
1916
|
+
rect_builder.add("end_region_statement", {});
|
|
1917
|
+
all_pour_commands.push(...rect_builder.build());
|
|
1918
|
+
} else if (element.shape === "polygon") {
|
|
1919
|
+
const { points } = element;
|
|
1920
|
+
if (points.length > 0) {
|
|
1921
|
+
const poly_builder = gerberBuilder().add("select_aperture", { aperture_number: 10 }).add("start_region_statement", {});
|
|
1922
|
+
poly_builder.add("move_operation", {
|
|
1923
|
+
x: points[0].x,
|
|
1924
|
+
y: mfy(points[0].y)
|
|
1925
|
+
});
|
|
1926
|
+
for (let i = 1; i < points.length; i++) {
|
|
1927
|
+
poly_builder.add("plot_operation", {
|
|
1928
|
+
x: points[i].x,
|
|
1929
|
+
y: mfy(points[i].y)
|
|
1930
|
+
});
|
|
1931
|
+
}
|
|
1932
|
+
poly_builder.add("plot_operation", {
|
|
1933
|
+
x: points[0].x,
|
|
1934
|
+
y: mfy(points[0].y)
|
|
1935
|
+
});
|
|
1936
|
+
poly_builder.add("end_region_statement", {});
|
|
1937
|
+
all_pour_commands.push(...poly_builder.build());
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
copper_glayer.push(...all_pour_commands);
|
|
1941
|
+
if (element.covered_with_solder_mask === false) {
|
|
1942
|
+
const mask_layer = glayers[getGerberLayerName(layer, "soldermask")];
|
|
1943
|
+
mask_layer.push(...all_pour_commands);
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1775
1948
|
for (const layer of ["top", "bottom", "edgecut"]) {
|
|
1776
1949
|
for (const element of soup) {
|
|
1777
1950
|
if (element.type === "pcb_trace") {
|
|
@@ -2251,164 +2424,6 @@ var convertSoupToGerberCommands = (soup, opts = {}) => {
|
|
|
2251
2424
|
}
|
|
2252
2425
|
ec_layer.push(...cutout_builder.build());
|
|
2253
2426
|
}
|
|
2254
|
-
} else if (element.type === "pcb_copper_pour" && layer === element.layer) {
|
|
2255
|
-
const copper_glayer = glayers[getGerberLayerName(layer, "copper")];
|
|
2256
|
-
const pour_builder = gerberBuilder().add("select_aperture", { aperture_number: 10 }).add("start_region_statement", {});
|
|
2257
|
-
if (element.shape === "brep") {
|
|
2258
|
-
const { brep_shape } = element;
|
|
2259
|
-
if (!brep_shape) continue;
|
|
2260
|
-
const { outer_ring, inner_rings } = brep_shape;
|
|
2261
|
-
const drawRing = (ring) => {
|
|
2262
|
-
if (!ring || ring.vertices.length === 0) return;
|
|
2263
|
-
pour_builder.add("move_operation", {
|
|
2264
|
-
x: ring.vertices[0].x,
|
|
2265
|
-
y: mfy(ring.vertices[0].y)
|
|
2266
|
-
});
|
|
2267
|
-
const vertices_loop = [...ring.vertices, ring.vertices[0]];
|
|
2268
|
-
for (let i = 0; i < vertices_loop.length - 1; i++) {
|
|
2269
|
-
const start = vertices_loop[i];
|
|
2270
|
-
const end = vertices_loop[i + 1];
|
|
2271
|
-
if (start.bulge && Math.abs(start.bulge) > 1e-9) {
|
|
2272
|
-
const bulge = (opts.flip_y_axis ? -1 : 1) * start.bulge;
|
|
2273
|
-
if (bulge > 0) {
|
|
2274
|
-
pour_builder.add(
|
|
2275
|
-
"set_movement_mode_to_counterclockwise_circular",
|
|
2276
|
-
{}
|
|
2277
|
-
);
|
|
2278
|
-
} else {
|
|
2279
|
-
pour_builder.add(
|
|
2280
|
-
"set_movement_mode_to_clockwise_circular",
|
|
2281
|
-
{}
|
|
2282
|
-
);
|
|
2283
|
-
}
|
|
2284
|
-
const p1 = { x: start.x, y: start.y };
|
|
2285
|
-
const p2 = { x: end.x, y: end.y };
|
|
2286
|
-
const dx = p2.x - p1.x;
|
|
2287
|
-
const dy = p2.y - p1.y;
|
|
2288
|
-
const d = Math.sqrt(dx * dx + dy * dy);
|
|
2289
|
-
if (d < 1e-9) {
|
|
2290
|
-
pour_builder.add("set_movement_mode_to_linear", {});
|
|
2291
|
-
pour_builder.add("plot_operation", {
|
|
2292
|
-
x: end.x,
|
|
2293
|
-
y: mfy(end.y)
|
|
2294
|
-
});
|
|
2295
|
-
continue;
|
|
2296
|
-
}
|
|
2297
|
-
const abs_b = Math.abs(bulge);
|
|
2298
|
-
const theta = 4 * Math.atan(abs_b);
|
|
2299
|
-
if (Math.abs(Math.sin(theta / 2)) < 1e-9) {
|
|
2300
|
-
pour_builder.add("set_movement_mode_to_linear", {});
|
|
2301
|
-
pour_builder.add("plot_operation", {
|
|
2302
|
-
x: end.x,
|
|
2303
|
-
y: mfy(end.y)
|
|
2304
|
-
});
|
|
2305
|
-
continue;
|
|
2306
|
-
}
|
|
2307
|
-
const R = d / (2 * Math.sin(theta / 2));
|
|
2308
|
-
const alpha = (Math.PI - theta) / 2;
|
|
2309
|
-
const phi = Math.atan2(dy, dx);
|
|
2310
|
-
const delta_angle = bulge > 0 ? alpha : -alpha;
|
|
2311
|
-
const angle_p1_center = phi + delta_angle;
|
|
2312
|
-
const Cx = p1.x + R * Math.cos(angle_p1_center);
|
|
2313
|
-
const Cy = p1.y + R * Math.sin(angle_p1_center);
|
|
2314
|
-
const i_offset = Cx - p1.x;
|
|
2315
|
-
const j_offset = Cy - p1.y;
|
|
2316
|
-
pour_builder.add("plot_operation", {
|
|
2317
|
-
x: end.x,
|
|
2318
|
-
y: mfy(end.y),
|
|
2319
|
-
i: i_offset,
|
|
2320
|
-
j: opts.flip_y_axis ? -j_offset : j_offset
|
|
2321
|
-
});
|
|
2322
|
-
} else {
|
|
2323
|
-
pour_builder.add("set_movement_mode_to_linear", {});
|
|
2324
|
-
pour_builder.add("plot_operation", { x: end.x, y: mfy(end.y) });
|
|
2325
|
-
}
|
|
2326
|
-
}
|
|
2327
|
-
};
|
|
2328
|
-
const reverseRing = (ring) => {
|
|
2329
|
-
const { vertices } = ring;
|
|
2330
|
-
if (!vertices || vertices.length === 0) return { vertices: [] };
|
|
2331
|
-
const n = vertices.length;
|
|
2332
|
-
const reversed_pts = [...vertices].reverse();
|
|
2333
|
-
const new_vertices = reversed_pts.map((pt, i) => {
|
|
2334
|
-
const bulge_v_idx = (n - 2 - i + n) % n;
|
|
2335
|
-
const bulge = vertices[bulge_v_idx].bulge;
|
|
2336
|
-
return { ...pt, bulge: bulge ? -bulge : void 0 };
|
|
2337
|
-
});
|
|
2338
|
-
return { vertices: new_vertices };
|
|
2339
|
-
};
|
|
2340
|
-
drawRing(reverseRing(outer_ring));
|
|
2341
|
-
if (inner_rings) {
|
|
2342
|
-
for (const inner_ring of inner_rings) {
|
|
2343
|
-
drawRing(reverseRing(inner_ring));
|
|
2344
|
-
}
|
|
2345
|
-
}
|
|
2346
|
-
} else if (element.shape === "rect") {
|
|
2347
|
-
const { center, width, height, rotation } = element;
|
|
2348
|
-
const w = width / 2;
|
|
2349
|
-
const h = height / 2;
|
|
2350
|
-
const points = [
|
|
2351
|
-
{ x: -w, y: h },
|
|
2352
|
-
// Top-left
|
|
2353
|
-
{ x: w, y: h },
|
|
2354
|
-
// Top-right
|
|
2355
|
-
{ x: w, y: -h },
|
|
2356
|
-
// Bottom-right
|
|
2357
|
-
{ x: -w, y: -h }
|
|
2358
|
-
// Bottom-left
|
|
2359
|
-
];
|
|
2360
|
-
let transformMatrix = identity();
|
|
2361
|
-
if (rotation) {
|
|
2362
|
-
const angle_rad = rotation * Math.PI / 180;
|
|
2363
|
-
transformMatrix = rotate(angle_rad);
|
|
2364
|
-
}
|
|
2365
|
-
transformMatrix = compose(
|
|
2366
|
-
translate(center.x, center.y),
|
|
2367
|
-
transformMatrix
|
|
2368
|
-
);
|
|
2369
|
-
const transformedPoints = points.map(
|
|
2370
|
-
(p) => applyToPoint(transformMatrix, p)
|
|
2371
|
-
);
|
|
2372
|
-
pour_builder.add("move_operation", {
|
|
2373
|
-
x: transformedPoints[0].x,
|
|
2374
|
-
y: mfy(transformedPoints[0].y)
|
|
2375
|
-
});
|
|
2376
|
-
for (let i = 1; i < transformedPoints.length; i++) {
|
|
2377
|
-
pour_builder.add("plot_operation", {
|
|
2378
|
-
x: transformedPoints[i].x,
|
|
2379
|
-
y: mfy(transformedPoints[i].y)
|
|
2380
|
-
});
|
|
2381
|
-
}
|
|
2382
|
-
pour_builder.add("plot_operation", {
|
|
2383
|
-
x: transformedPoints[0].x,
|
|
2384
|
-
y: mfy(transformedPoints[0].y)
|
|
2385
|
-
});
|
|
2386
|
-
} else if (element.shape === "polygon") {
|
|
2387
|
-
const { points } = element;
|
|
2388
|
-
if (points.length > 0) {
|
|
2389
|
-
pour_builder.add("move_operation", {
|
|
2390
|
-
x: points[0].x,
|
|
2391
|
-
y: mfy(points[0].y)
|
|
2392
|
-
});
|
|
2393
|
-
for (let i = 1; i < points.length; i++) {
|
|
2394
|
-
pour_builder.add("plot_operation", {
|
|
2395
|
-
x: points[i].x,
|
|
2396
|
-
y: mfy(points[i].y)
|
|
2397
|
-
});
|
|
2398
|
-
}
|
|
2399
|
-
pour_builder.add("plot_operation", {
|
|
2400
|
-
x: points[0].x,
|
|
2401
|
-
y: mfy(points[0].y)
|
|
2402
|
-
});
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
pour_builder.add("end_region_statement", {});
|
|
2406
|
-
const pour_commands = pour_builder.build();
|
|
2407
|
-
copper_glayer.push(...pour_commands);
|
|
2408
|
-
if (element.covered_with_solder_mask === false) {
|
|
2409
|
-
const mask_layer = glayers[getGerberLayerName(layer, "soldermask")];
|
|
2410
|
-
mask_layer.push(...pour_commands);
|
|
2411
|
-
}
|
|
2412
2427
|
}
|
|
2413
2428
|
}
|
|
2414
2429
|
}
|
|
@@ -2430,4 +2445,4 @@ export {
|
|
|
2430
2445
|
stringifyGerberCommands,
|
|
2431
2446
|
convertSoupToGerberCommands
|
|
2432
2447
|
};
|
|
2433
|
-
//# sourceMappingURL=chunk-
|
|
2448
|
+
//# sourceMappingURL=chunk-VM5XFQ53.js.map
|