@willcgage/module-schematic 0.48.0 → 0.49.1
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/index.cjs +46 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +46 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -478,6 +478,9 @@ function moduleFootprint(input) {
|
|
|
478
478
|
// endplate A's face (the far face would be a spurious plate at the throat).
|
|
479
479
|
endplateFaces: input.loop ? endplateFaceSegments(centerline, widthA, widthB, offA, offB).slice(0, 1) : endplateFaceSegments(centerline, widthA, widthB, offA, offB),
|
|
480
480
|
outline: sectionOutlines.length || !authored ? null : sampleBenchworkOutline(authored),
|
|
481
|
+
// The donut hole, arc-sampled — only when there's a solid outline to punch it
|
|
482
|
+
// out of (a sectioned module isn't a donut). Renderers cut it from `outline`.
|
|
483
|
+
outlineInner: sectionOutlines.length || !authored || !input.outlineInner || input.outlineInner.length < 3 ? null : sampleBenchworkOutline(input.outlineInner),
|
|
481
484
|
sectionOutlines
|
|
482
485
|
};
|
|
483
486
|
}
|
|
@@ -559,6 +562,7 @@ function emptyEditorState(lengthInches) {
|
|
|
559
562
|
endplateWidths: {},
|
|
560
563
|
endplateTrackOffsets: {},
|
|
561
564
|
outline: [],
|
|
565
|
+
outlineInner: [],
|
|
562
566
|
sectionBreaks: [],
|
|
563
567
|
sections: [],
|
|
564
568
|
controlPoints: [],
|
|
@@ -795,6 +799,8 @@ function stateToDoc(state, recordNumber) {
|
|
|
795
799
|
// Benchwork footprint outline (module-local inches); only when it's a real
|
|
796
800
|
// ring (≥ 3 vertices).
|
|
797
801
|
...state.outline.length >= 3 ? { outline: state.outline } : {},
|
|
802
|
+
// Benchwork hole (donut inner boundary), when it's a real ring.
|
|
803
|
+
...state.outlineInner.length >= 3 ? { outlineInner: state.outlineInner } : {},
|
|
798
804
|
// Internal section joints (inches from A), when the module has more than one.
|
|
799
805
|
...state.sectionBreaks.length ? { sectionBreaks: state.sectionBreaks } : {},
|
|
800
806
|
// Sections as objects — emitted only once the owner has some, so a module
|
|
@@ -886,6 +892,11 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
886
892
|
y: p.y,
|
|
887
893
|
...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
|
|
888
894
|
}));
|
|
895
|
+
const outlineInner = (d.outlineInner ?? []).filter((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y)).map((p) => ({
|
|
896
|
+
x: p.x,
|
|
897
|
+
y: p.y,
|
|
898
|
+
...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
|
|
899
|
+
}));
|
|
889
900
|
const mainPath = trackPath(d.mainPath) ?? [];
|
|
890
901
|
const main2Track_ = (d.tracks ?? []).find((t) => t.id === MAIN2_TRACK_ID);
|
|
891
902
|
const main2Path = trackPath(d.main2Path ?? main2Track_?.path) ?? [];
|
|
@@ -909,6 +920,7 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
909
920
|
endplateWidths,
|
|
910
921
|
endplateTrackOffsets,
|
|
911
922
|
outline,
|
|
923
|
+
outlineInner,
|
|
912
924
|
sectionBreaks: (d.sectionBreaks ?? []).filter((n) => Number.isFinite(n)).map((n) => sc(n)),
|
|
913
925
|
sections: moduleSections(d),
|
|
914
926
|
mainPath,
|
|
@@ -1334,36 +1346,7 @@ function returnLoop(shape, opts) {
|
|
|
1334
1346
|
for (let i = 0; i <= steps; i++) out.push({ x: cx + r * Math.cos(a0 + (a12 - a0) * i / steps), y: cy + r * Math.sin(a0 + (a12 - a0) * i / steps) });
|
|
1335
1347
|
return out;
|
|
1336
1348
|
};
|
|
1337
|
-
|
|
1338
|
-
const s = 2 * R;
|
|
1339
|
-
const loop2 = [
|
|
1340
|
-
{ x: L, y: 0 },
|
|
1341
|
-
{ x: L, y: R },
|
|
1342
|
-
{ x: L + s, y: R },
|
|
1343
|
-
{ x: L + s, y: -R },
|
|
1344
|
-
{ x: L, y: -R },
|
|
1345
|
-
{ x: L, y: 0 }
|
|
1346
|
-
];
|
|
1347
|
-
return {
|
|
1348
|
-
throat: T,
|
|
1349
|
-
loop: rd(loop2),
|
|
1350
|
-
wyeLegs: [rd([T, { x: L, y: R }]), rd([T, { x: L, y: -R }])],
|
|
1351
|
-
wyeHalfAngleDeg: 90,
|
|
1352
|
-
outlineOuter: rd([
|
|
1353
|
-
{ x: 0, y: hw },
|
|
1354
|
-
{ x: L + s + hw, y: hw },
|
|
1355
|
-
{ x: L + s + hw, y: -R - hw },
|
|
1356
|
-
{ x: 0, y: -R - hw }
|
|
1357
|
-
]),
|
|
1358
|
-
outlineInner: rd([
|
|
1359
|
-
{ x: L + hw, y: R - hw },
|
|
1360
|
-
{ x: L + s - hw, y: R - hw },
|
|
1361
|
-
{ x: L + s - hw, y: -R + hw },
|
|
1362
|
-
{ x: L + hw, y: -R + hw }
|
|
1363
|
-
])
|
|
1364
|
-
};
|
|
1365
|
-
}
|
|
1366
|
-
const D = shape === "circle" ? R * 1.15 : R * 1.6;
|
|
1349
|
+
const D = shape === "circle" || shape === "square" ? R * 1.15 : R * 1.6;
|
|
1367
1350
|
const offY = shape === "offset-teardrop" ? R * 0.7 : 0;
|
|
1368
1351
|
const C = { x: L + D, y: offY };
|
|
1369
1352
|
const dist = Math.hypot(C.x - T.x, C.y - T.y);
|
|
@@ -1381,15 +1364,47 @@ function returnLoop(shape, opts) {
|
|
|
1381
1364
|
const xBot = C.x - Math.sqrt(Math.max(0, rr * rr - (-hw - C.y) ** 2));
|
|
1382
1365
|
const tTop = Math.atan2(hw - C.y, xTop - C.x);
|
|
1383
1366
|
const tBot = Math.atan2(-hw - C.y, xBot - C.x);
|
|
1367
|
+
let end = tBot;
|
|
1368
|
+
while (end >= tTop) end -= 2 * Math.PI;
|
|
1384
1369
|
return [
|
|
1385
1370
|
{ x: 0, y: hw },
|
|
1386
1371
|
{ x: xTop, y: hw },
|
|
1387
|
-
...arc(C.x, C.y, rr, tTop,
|
|
1372
|
+
...arc(C.x, C.y, rr, tTop, end, 48).slice(1, -1),
|
|
1388
1373
|
{ x: xBot, y: -hw },
|
|
1389
1374
|
{ x: 0, y: -hw }
|
|
1390
1375
|
];
|
|
1391
1376
|
};
|
|
1392
1377
|
const Ri = R - hw;
|
|
1378
|
+
if (shape === "square") {
|
|
1379
|
+
const xL = C.x - R - hw;
|
|
1380
|
+
const xR = C.x + R + hw;
|
|
1381
|
+
const yT = R + hw;
|
|
1382
|
+
const outerSquare = [
|
|
1383
|
+
{ x: 0, y: hw },
|
|
1384
|
+
{ x: xL, y: hw },
|
|
1385
|
+
{ x: xL, y: yT },
|
|
1386
|
+
{ x: xR, y: yT },
|
|
1387
|
+
{ x: xR, y: -yT },
|
|
1388
|
+
{ x: xL, y: -yT },
|
|
1389
|
+
{ x: xL, y: -hw },
|
|
1390
|
+
{ x: 0, y: -hw }
|
|
1391
|
+
];
|
|
1392
|
+
const iHalf = (R - hw) / Math.SQRT2;
|
|
1393
|
+
const holeSquare = iHalf > 2 ? [
|
|
1394
|
+
{ x: C.x - iHalf, y: iHalf },
|
|
1395
|
+
{ x: C.x + iHalf, y: iHalf },
|
|
1396
|
+
{ x: C.x + iHalf, y: -iHalf },
|
|
1397
|
+
{ x: C.x - iHalf, y: -iHalf }
|
|
1398
|
+
] : [];
|
|
1399
|
+
return {
|
|
1400
|
+
throat: T,
|
|
1401
|
+
loop: rd(loop),
|
|
1402
|
+
wyeLegs: [rd([T, P1]), rd([T, P2])],
|
|
1403
|
+
wyeHalfAngleDeg: r2(half * 180 / Math.PI),
|
|
1404
|
+
outlineOuter: rd(outerSquare),
|
|
1405
|
+
outlineInner: rd(holeSquare)
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1393
1408
|
return {
|
|
1394
1409
|
throat: T,
|
|
1395
1410
|
loop: rd(loop),
|