@willcgage/module-schematic 0.69.0 → 0.71.0
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 +45 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -12
- package/dist/index.d.ts +71 -12
- package/dist/index.js +44 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -471,8 +471,12 @@ function moduleFootprint(input) {
|
|
|
471
471
|
const widthA = endplateWidthFor(input.endplateWidths, "A");
|
|
472
472
|
const widthB = endplateWidthFor(input.endplateWidths, "B");
|
|
473
473
|
const authored = benchworkOutline(input);
|
|
474
|
-
const
|
|
475
|
-
|
|
474
|
+
const offOf = (i, id) => input.endplateTrackOffsets?.[id] ?? endplateCentreOffsetInches({
|
|
475
|
+
config: input.endplateConfigs?.[i],
|
|
476
|
+
main2Below: input.mainsSwapped === true
|
|
477
|
+
});
|
|
478
|
+
const offA = offOf(0, "A");
|
|
479
|
+
const offB = offOf(1, "B");
|
|
476
480
|
const secs = input.sections ?? [];
|
|
477
481
|
const sectionsOwnShape = secs.length > 1 || secs.some((s) => (s.outline?.length ?? 0) >= 3);
|
|
478
482
|
const sectionOutlines = sectionsOwnShape ? sectionFootprints(input, {
|
|
@@ -485,9 +489,10 @@ function moduleFootprint(input) {
|
|
|
485
489
|
return {
|
|
486
490
|
centerline,
|
|
487
491
|
band: benchworkBand(centerline, widthA, widthB, offA, offB),
|
|
488
|
-
//
|
|
489
|
-
//
|
|
490
|
-
|
|
492
|
+
// Only emit a face where the module actually presents one. A loop's
|
|
493
|
+
// centre-line ends at the THROAT, and an end of the line / pocket simply
|
|
494
|
+
// stops — a far face there is a plate the module hasn't got (#191).
|
|
495
|
+
endplateFaces: hasNoFarEndplate(input) ? endplateFaceSegments(centerline, widthA, widthB, offA, offB).slice(0, 1) : endplateFaceSegments(centerline, widthA, widthB, offA, offB),
|
|
491
496
|
outline: sectionOutlines.length || !authored ? null : sampleBenchworkOutline(authored),
|
|
492
497
|
// The donut hole, arc-sampled — only when there's a solid outline to punch it
|
|
493
498
|
// out of (a sectioned module isn't a donut). Renderers cut it from `outline`.
|
|
@@ -495,13 +500,19 @@ function moduleFootprint(input) {
|
|
|
495
500
|
sectionOutlines
|
|
496
501
|
};
|
|
497
502
|
}
|
|
498
|
-
function
|
|
499
|
-
const v = -endplateTrackOffsetInches(
|
|
503
|
+
function endplateCentreOffsetInches(input) {
|
|
504
|
+
const v = -endplateTrackOffsetInches(
|
|
505
|
+
input.authoredTrackOffsetInches,
|
|
506
|
+
input.config ?? void 0,
|
|
507
|
+
input.main2Below
|
|
508
|
+
);
|
|
500
509
|
return v === 0 ? 0 : v;
|
|
501
510
|
}
|
|
502
|
-
function endplateTrackOffsetInches(authored, config) {
|
|
511
|
+
function endplateTrackOffsetInches(authored, config, main2Below = false) {
|
|
503
512
|
if (typeof authored === "number" && Number.isFinite(authored)) return authored;
|
|
504
|
-
|
|
513
|
+
if (config !== "double") return 0;
|
|
514
|
+
const half = FREEMO_TRACK_SPACING_INCHES / 2;
|
|
515
|
+
return main2Below ? half : -half;
|
|
505
516
|
}
|
|
506
517
|
function checkEndplateWidth(input) {
|
|
507
518
|
const width = endplateWidthInches(input);
|
|
@@ -513,8 +524,13 @@ function checkEndplateWidth(input) {
|
|
|
513
524
|
requiredInches: FREEMO_ENDPLATE_WIDTH_MIN_INCHES
|
|
514
525
|
});
|
|
515
526
|
}
|
|
516
|
-
const off = endplateTrackOffsetInches(
|
|
517
|
-
|
|
527
|
+
const off = endplateTrackOffsetInches(
|
|
528
|
+
input.trackOffsetInches,
|
|
529
|
+
input.config ?? void 0,
|
|
530
|
+
input.main2Below
|
|
531
|
+
);
|
|
532
|
+
const second = off + (input.main2Below ? -1 : 1) * FREEMO_TRACK_SPACING_INCHES;
|
|
533
|
+
const centres = input.config === "double" ? [off, second] : [off];
|
|
518
534
|
const worst = Math.max(...centres.map((c) => Math.abs(c)));
|
|
519
535
|
const clearance = width / 2 - worst;
|
|
520
536
|
if (clearance < FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES) {
|
|
@@ -525,6 +541,18 @@ function checkEndplateWidth(input) {
|
|
|
525
541
|
requiredInches: required
|
|
526
542
|
});
|
|
527
543
|
}
|
|
544
|
+
if (input.config === "double") {
|
|
545
|
+
const mid = (off + second) / 2;
|
|
546
|
+
if (Math.abs(mid) > 0.01) {
|
|
547
|
+
issues.push({
|
|
548
|
+
code: "offcentre",
|
|
549
|
+
message: `The two tracks sit ${round2(Math.abs(mid))}\u2033 off the centre of this endplate. The standard recommends they straddle it \u2014 Main 1 at ${round2((input.main2Below ? 1 : -1) * (FREEMO_TRACK_SPACING_INCHES / 2))}\u2033. Clear the offset to use that.`,
|
|
550
|
+
// Not a width problem — no wider plate fixes it — so hand back the
|
|
551
|
+
// width unchanged rather than imply one would.
|
|
552
|
+
requiredInches: width
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
528
556
|
return issues;
|
|
529
557
|
}
|
|
530
558
|
var round2 = (n) => Math.round(n * 100) / 100;
|
|
@@ -533,6 +561,9 @@ function endplateWidthFor(widths, id) {
|
|
|
533
561
|
const w = widths?.[id];
|
|
534
562
|
return typeof w === "number" && w > 0 ? w : FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
535
563
|
}
|
|
564
|
+
function hasNoFarEndplate(input) {
|
|
565
|
+
return input.geometryType === "dead_end" || input.loop === true || input.endplateConfigs?.[1] === "none";
|
|
566
|
+
}
|
|
536
567
|
function isLoopDoc(doc) {
|
|
537
568
|
return doc.loop === true;
|
|
538
569
|
}
|
|
@@ -1993,7 +2024,7 @@ function deriveEndplatePoses(geo) {
|
|
|
1993
2024
|
trackOffsets: offsetsFor(cfg(0), half)
|
|
1994
2025
|
})
|
|
1995
2026
|
);
|
|
1996
|
-
const noB = geo
|
|
2027
|
+
const noB = hasNoFarEndplate(geo);
|
|
1997
2028
|
const end = sectionedEndPose({ sections: geo.sections });
|
|
1998
2029
|
if (!noB && end) {
|
|
1999
2030
|
poses.push(
|
|
@@ -2173,15 +2204,16 @@ exports.deriveEndplatePoses = deriveEndplatePoses;
|
|
|
2173
2204
|
exports.divergeSideForHand = divergeSideForHand;
|
|
2174
2205
|
exports.docToState = docToState;
|
|
2175
2206
|
exports.emptyEditorState = emptyEditorState;
|
|
2207
|
+
exports.endplateCentreOffsetInches = endplateCentreOffsetInches;
|
|
2176
2208
|
exports.endplateFaceSegments = endplateFaceSegments;
|
|
2177
2209
|
exports.endplateLead = endplateLead;
|
|
2178
|
-
exports.endplateTrackOffsetFor = endplateTrackOffsetFor;
|
|
2179
2210
|
exports.endplateTrackOffsetInches = endplateTrackOffsetInches;
|
|
2180
2211
|
exports.endplateWidthInches = endplateWidthInches;
|
|
2181
2212
|
exports.frogCasting = frogCasting;
|
|
2182
2213
|
exports.frogNumberFromName = frogNumberFromName;
|
|
2183
2214
|
exports.fromSectionRelative = fromSectionRelative;
|
|
2184
2215
|
exports.geometryTurnDegrees = geometryTurnDegrees;
|
|
2216
|
+
exports.hasNoFarEndplate = hasNoFarEndplate;
|
|
2185
2217
|
exports.importedPartToTrackPart = importedPartToTrackPart;
|
|
2186
2218
|
exports.inchesToScaleFeet = inchesToScaleFeet;
|
|
2187
2219
|
exports.isLoopDoc = isLoopDoc;
|