@willcgage/module-schematic 0.26.0 → 0.27.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 +53 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +54 -3
- package/dist/index.d.ts +54 -3
- package/dist/index.js +50 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
var FREEMO_ENDPLATE_WIDTH_MIN_INCHES = 12;
|
|
5
5
|
var FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES = 24;
|
|
6
|
+
var FREEMO_TRACK_SPACING_INCHES = 1.125;
|
|
7
|
+
var FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES = 4;
|
|
6
8
|
function endplateWidthInches(ep) {
|
|
7
9
|
const w = ep?.widthInches;
|
|
8
10
|
return typeof w === "number" && w > 0 ? w : FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
@@ -144,37 +146,74 @@ function centerlineFractions(center) {
|
|
|
144
146
|
const total = cum[cum.length - 1] || 1;
|
|
145
147
|
return cum.map((d) => d / total);
|
|
146
148
|
}
|
|
147
|
-
function benchworkBand(center, widthA = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, widthB = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES) {
|
|
149
|
+
function benchworkBand(center, widthA = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, widthB = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, offsetA = 0, offsetB = 0) {
|
|
148
150
|
if (center.length < 2) return [];
|
|
149
151
|
const n = centerlineNormals(center);
|
|
150
152
|
const f = centerlineFractions(center);
|
|
151
153
|
const half = (i) => (widthA * (1 - f[i]) + widthB * f[i]) / 2;
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
+
const off = (i) => offsetA * (1 - f[i]) + offsetB * f[i];
|
|
155
|
+
const left = center.map((p, i) => ({
|
|
156
|
+
x: p.x + n[i].x * (off(i) + half(i)),
|
|
157
|
+
y: p.y + n[i].y * (off(i) + half(i))
|
|
158
|
+
}));
|
|
159
|
+
const right = center.map((p, i) => ({
|
|
160
|
+
x: p.x + n[i].x * (off(i) - half(i)),
|
|
161
|
+
y: p.y + n[i].y * (off(i) - half(i))
|
|
162
|
+
}));
|
|
154
163
|
return [...left, ...right.reverse()];
|
|
155
164
|
}
|
|
156
|
-
function endplateFaceSegments(center, widthA = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, widthB = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES) {
|
|
165
|
+
function endplateFaceSegments(center, widthA = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, widthB = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, offsetA = 0, offsetB = 0) {
|
|
157
166
|
if (center.length < 2) return [];
|
|
158
167
|
const n = centerlineNormals(center);
|
|
159
|
-
const face = (i, w) => ({
|
|
160
|
-
p1: { x: center[i].x + n[i].x * (w / 2), y: center[i].y + n[i].y * (w / 2) },
|
|
161
|
-
p2: { x: center[i].x
|
|
168
|
+
const face = (i, w, o) => ({
|
|
169
|
+
p1: { x: center[i].x + n[i].x * (o + w / 2), y: center[i].y + n[i].y * (o + w / 2) },
|
|
170
|
+
p2: { x: center[i].x + n[i].x * (o - w / 2), y: center[i].y + n[i].y * (o - w / 2) },
|
|
162
171
|
mid: { x: center[i].x, y: center[i].y }
|
|
163
172
|
});
|
|
164
|
-
return [face(0, widthA), face(center.length - 1, widthB)];
|
|
173
|
+
return [face(0, widthA, offsetA), face(center.length - 1, widthB, offsetB)];
|
|
165
174
|
}
|
|
166
175
|
function moduleFootprint(input) {
|
|
167
176
|
const centerline = moduleCenterline(input);
|
|
168
177
|
const widthA = endplateWidthFor(input.endplateWidths, "A");
|
|
169
178
|
const widthB = endplateWidthFor(input.endplateWidths, "B");
|
|
170
179
|
const authored = benchworkOutline(input);
|
|
180
|
+
const offA = input.endplateTrackOffsets?.["A"] ?? 0;
|
|
181
|
+
const offB = input.endplateTrackOffsets?.["B"] ?? 0;
|
|
171
182
|
return {
|
|
172
183
|
centerline,
|
|
173
|
-
band: benchworkBand(centerline, widthA, widthB),
|
|
174
|
-
endplateFaces: endplateFaceSegments(centerline, widthA, widthB),
|
|
184
|
+
band: benchworkBand(centerline, widthA, widthB, offA, offB),
|
|
185
|
+
endplateFaces: endplateFaceSegments(centerline, widthA, widthB, offA, offB),
|
|
175
186
|
outline: authored ? sampleBenchworkOutline(authored) : null
|
|
176
187
|
};
|
|
177
188
|
}
|
|
189
|
+
function endplateTrackOffsetFor(config) {
|
|
190
|
+
return config === "double" ? FREEMO_TRACK_SPACING_INCHES / 2 : 0;
|
|
191
|
+
}
|
|
192
|
+
function checkEndplateWidth(input) {
|
|
193
|
+
const width = endplateWidthInches(input);
|
|
194
|
+
const issues = [];
|
|
195
|
+
if (width < FREEMO_ENDPLATE_WIDTH_MIN_INCHES) {
|
|
196
|
+
issues.push({
|
|
197
|
+
code: "narrow",
|
|
198
|
+
message: `Endplate is ${round2(width)}\u2033 wide \u2014 the standard requires at least ${FREEMO_ENDPLATE_WIDTH_MIN_INCHES}\u2033.`,
|
|
199
|
+
requiredInches: FREEMO_ENDPLATE_WIDTH_MIN_INCHES
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
const off = input.trackOffsetInches ?? 0;
|
|
203
|
+
const centres = input.config === "double" ? [off - FREEMO_TRACK_SPACING_INCHES / 2, off + FREEMO_TRACK_SPACING_INCHES / 2] : [off];
|
|
204
|
+
const worst = Math.max(...centres.map((c) => Math.abs(c)));
|
|
205
|
+
const clearance = width / 2 - worst;
|
|
206
|
+
if (clearance < FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES) {
|
|
207
|
+
const required = 2 * (worst + FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES);
|
|
208
|
+
issues.push({
|
|
209
|
+
code: "clearance",
|
|
210
|
+
message: `Track sits ${round2(clearance)}\u2033 from the fascia \u2014 the standard requires at least ${FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES}\u2033. Widen this end to ${round2(required)}\u2033` + (off !== 0 ? " or move the track back toward the centre." : "."),
|
|
211
|
+
requiredInches: required
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return issues;
|
|
215
|
+
}
|
|
216
|
+
var round2 = (n) => Math.round(n * 100) / 100;
|
|
178
217
|
function endplateWidthFor(widths, id) {
|
|
179
218
|
const w = widths?.[id];
|
|
180
219
|
return typeof w === "number" && w > 0 ? w : FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
@@ -1039,8 +1078,10 @@ function poseOverridesFromDoc(doc) {
|
|
|
1039
1078
|
return out;
|
|
1040
1079
|
}
|
|
1041
1080
|
|
|
1081
|
+
exports.FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES = FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES;
|
|
1042
1082
|
exports.FREEMO_ENDPLATE_WIDTH_MIN_INCHES = FREEMO_ENDPLATE_WIDTH_MIN_INCHES;
|
|
1043
1083
|
exports.FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
1084
|
+
exports.FREEMO_TRACK_SPACING_INCHES = FREEMO_TRACK_SPACING_INCHES;
|
|
1044
1085
|
exports.MAIN2_TRACK_ID = MAIN2_TRACK_ID;
|
|
1045
1086
|
exports.MAIN_TRACK_ID = MAIN_TRACK_ID;
|
|
1046
1087
|
exports.N_CAR_LENGTH_INCHES = N_CAR_LENGTH_INCHES;
|
|
@@ -1052,11 +1093,13 @@ exports.buildCrossover = buildCrossover;
|
|
|
1052
1093
|
exports.buildPassingSiding = buildPassingSiding;
|
|
1053
1094
|
exports.buildTransition = buildTransition;
|
|
1054
1095
|
exports.carCapacity = carCapacity;
|
|
1096
|
+
exports.checkEndplateWidth = checkEndplateWidth;
|
|
1055
1097
|
exports.deriveEndplatePoses = deriveEndplatePoses;
|
|
1056
1098
|
exports.divergeSideForHand = divergeSideForHand;
|
|
1057
1099
|
exports.docToState = docToState;
|
|
1058
1100
|
exports.emptyEditorState = emptyEditorState;
|
|
1059
1101
|
exports.endplateFaceSegments = endplateFaceSegments;
|
|
1102
|
+
exports.endplateTrackOffsetFor = endplateTrackOffsetFor;
|
|
1060
1103
|
exports.endplateWidthInches = endplateWidthInches;
|
|
1061
1104
|
exports.geometryTurnDegrees = geometryTurnDegrees;
|
|
1062
1105
|
exports.inchesToScaleFeet = inchesToScaleFeet;
|