@willcgage/module-schematic 0.15.0 → 0.16.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 +61 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +61 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -165,17 +165,32 @@ interface ModuleSchematicDoc {
|
|
|
165
165
|
/** @deprecated pre-grouping flat signals; read for back-compat. */
|
|
166
166
|
signals?: SchematicSignal[];
|
|
167
167
|
}
|
|
168
|
-
/** A benchwork-outline vertex, module-local inches.
|
|
168
|
+
/** A benchwork-outline vertex, module-local inches. The edge from this vertex
|
|
169
|
+
* to the NEXT one is a straight line, unless `bulge` is set — then it's a
|
|
170
|
+
* circular arc whose midpoint is offset `bulge` inches (signed: + bows to the
|
|
171
|
+
* left of the P→next direction) perpendicular from the chord. */
|
|
169
172
|
interface BenchworkPoint {
|
|
170
173
|
x: number;
|
|
171
174
|
y: number;
|
|
175
|
+
bulge?: number;
|
|
172
176
|
}
|
|
173
177
|
/** The authored benchwork outline, or null when a module hasn't drawn one
|
|
174
178
|
* (renderers then fall back to a band derived from the endplate widths). A
|
|
175
|
-
* valid outline needs at least 3 points. */
|
|
179
|
+
* valid outline needs at least 3 points. Normalises each vertex to {x, y, bulge?}. */
|
|
176
180
|
declare function benchworkOutline(doc: {
|
|
177
181
|
outline?: BenchworkPoint[] | null;
|
|
178
182
|
} | null | undefined): BenchworkPoint[] | null;
|
|
183
|
+
/**
|
|
184
|
+
* Expand a benchwork outline (whose edges may be arcs) into a dense closed
|
|
185
|
+
* polyline for rendering — the SAME sampling both the Repository preview and
|
|
186
|
+
* Free-Dispatcher use, so a curve looks identical in both. Straight edges emit
|
|
187
|
+
* just their start vertex; a bulged edge emits `segsPerArc` points along the
|
|
188
|
+
* circular arc through the two endpoints and the bulged midpoint.
|
|
189
|
+
*/
|
|
190
|
+
declare function sampleBenchworkOutline(pts: BenchworkPoint[], segsPerArc?: number): {
|
|
191
|
+
x: number;
|
|
192
|
+
y: number;
|
|
193
|
+
}[];
|
|
179
194
|
/** Whether a doc is a single-endplate turnback (explicit flag or one endplate). */
|
|
180
195
|
declare function isLoopDoc(doc: ModuleSchematicDoc): boolean;
|
|
181
196
|
declare const MAIN_TRACK_ID = "main";
|
|
@@ -544,4 +559,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
544
559
|
heading: number;
|
|
545
560
|
}>;
|
|
546
561
|
|
|
547
|
-
export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_SCALE_RATIO, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, scaleFeetToInches, stateToDoc };
|
|
562
|
+
export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_SCALE_RATIO, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, scaleFeetToInches, stateToDoc };
|
package/dist/index.d.ts
CHANGED
|
@@ -165,17 +165,32 @@ interface ModuleSchematicDoc {
|
|
|
165
165
|
/** @deprecated pre-grouping flat signals; read for back-compat. */
|
|
166
166
|
signals?: SchematicSignal[];
|
|
167
167
|
}
|
|
168
|
-
/** A benchwork-outline vertex, module-local inches.
|
|
168
|
+
/** A benchwork-outline vertex, module-local inches. The edge from this vertex
|
|
169
|
+
* to the NEXT one is a straight line, unless `bulge` is set — then it's a
|
|
170
|
+
* circular arc whose midpoint is offset `bulge` inches (signed: + bows to the
|
|
171
|
+
* left of the P→next direction) perpendicular from the chord. */
|
|
169
172
|
interface BenchworkPoint {
|
|
170
173
|
x: number;
|
|
171
174
|
y: number;
|
|
175
|
+
bulge?: number;
|
|
172
176
|
}
|
|
173
177
|
/** The authored benchwork outline, or null when a module hasn't drawn one
|
|
174
178
|
* (renderers then fall back to a band derived from the endplate widths). A
|
|
175
|
-
* valid outline needs at least 3 points. */
|
|
179
|
+
* valid outline needs at least 3 points. Normalises each vertex to {x, y, bulge?}. */
|
|
176
180
|
declare function benchworkOutline(doc: {
|
|
177
181
|
outline?: BenchworkPoint[] | null;
|
|
178
182
|
} | null | undefined): BenchworkPoint[] | null;
|
|
183
|
+
/**
|
|
184
|
+
* Expand a benchwork outline (whose edges may be arcs) into a dense closed
|
|
185
|
+
* polyline for rendering — the SAME sampling both the Repository preview and
|
|
186
|
+
* Free-Dispatcher use, so a curve looks identical in both. Straight edges emit
|
|
187
|
+
* just their start vertex; a bulged edge emits `segsPerArc` points along the
|
|
188
|
+
* circular arc through the two endpoints and the bulged midpoint.
|
|
189
|
+
*/
|
|
190
|
+
declare function sampleBenchworkOutline(pts: BenchworkPoint[], segsPerArc?: number): {
|
|
191
|
+
x: number;
|
|
192
|
+
y: number;
|
|
193
|
+
}[];
|
|
179
194
|
/** Whether a doc is a single-endplate turnback (explicit flag or one endplate). */
|
|
180
195
|
declare function isLoopDoc(doc: ModuleSchematicDoc): boolean;
|
|
181
196
|
declare const MAIN_TRACK_ID = "main";
|
|
@@ -544,4 +559,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
544
559
|
heading: number;
|
|
545
560
|
}>;
|
|
546
561
|
|
|
547
|
-
export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_SCALE_RATIO, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, scaleFeetToInches, stateToDoc };
|
|
562
|
+
export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_SCALE_RATIO, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, scaleFeetToInches, stateToDoc };
|
package/dist/index.js
CHANGED
|
@@ -6,11 +6,63 @@ function endplateWidthInches(ep) {
|
|
|
6
6
|
return typeof w === "number" && w > 0 ? w : FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
7
7
|
}
|
|
8
8
|
function benchworkOutline(doc) {
|
|
9
|
-
const pts = (doc?.outline ?? []).filter(
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const pts = (doc?.outline ?? []).filter((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y)).map((p) => ({
|
|
10
|
+
x: p.x,
|
|
11
|
+
y: p.y,
|
|
12
|
+
...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
|
|
13
|
+
}));
|
|
12
14
|
return pts.length >= 3 ? pts : null;
|
|
13
15
|
}
|
|
16
|
+
function sampleBenchworkOutline(pts, segsPerArc = 20) {
|
|
17
|
+
const n = pts.length;
|
|
18
|
+
if (n < 2) return pts.map((p) => ({ x: p.x, y: p.y }));
|
|
19
|
+
const out = [];
|
|
20
|
+
for (let i = 0; i < n; i++) {
|
|
21
|
+
const p0 = pts[i];
|
|
22
|
+
const p1 = pts[(i + 1) % n];
|
|
23
|
+
out.push({ x: p0.x, y: p0.y });
|
|
24
|
+
const bulge = p0.bulge ?? 0;
|
|
25
|
+
if (!bulge) continue;
|
|
26
|
+
const dx = p1.x - p0.x;
|
|
27
|
+
const dy = p1.y - p0.y;
|
|
28
|
+
const c = Math.hypot(dx, dy);
|
|
29
|
+
if (c < 1e-6) continue;
|
|
30
|
+
const nx = -dy / c;
|
|
31
|
+
const ny = dx / c;
|
|
32
|
+
const mid = { x: (p0.x + p1.x) / 2 + nx * bulge, y: (p0.y + p1.y) / 2 + ny * bulge };
|
|
33
|
+
const circ = circleThrough(p0, mid, p1);
|
|
34
|
+
if (!circ) continue;
|
|
35
|
+
const a0 = Math.atan2(p0.y - circ.cy, p0.x - circ.cx);
|
|
36
|
+
const am = Math.atan2(mid.y - circ.cy, mid.x - circ.cx);
|
|
37
|
+
const a1 = Math.atan2(p1.y - circ.cy, p1.x - circ.cx);
|
|
38
|
+
const sweep = arcSweep(a0, a1, am);
|
|
39
|
+
for (let s = 1; s < segsPerArc; s++) {
|
|
40
|
+
const a = a0 + sweep * s / segsPerArc;
|
|
41
|
+
out.push({ x: circ.cx + circ.r * Math.cos(a), y: circ.cy + circ.r * Math.sin(a) });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
function circleThrough(a, b, c) {
|
|
47
|
+
const d = 2 * (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
|
|
48
|
+
if (Math.abs(d) < 1e-9) return null;
|
|
49
|
+
const a2 = a.x * a.x + a.y * a.y;
|
|
50
|
+
const b2 = b.x * b.x + b.y * b.y;
|
|
51
|
+
const c2 = c.x * c.x + c.y * c.y;
|
|
52
|
+
const cx = (a2 * (b.y - c.y) + b2 * (c.y - a.y) + c2 * (a.y - b.y)) / d;
|
|
53
|
+
const cy = (a2 * (c.x - b.x) + b2 * (a.x - c.x) + c2 * (b.x - a.x)) / d;
|
|
54
|
+
return { cx, cy, r: Math.hypot(a.x - cx, a.y - cy) };
|
|
55
|
+
}
|
|
56
|
+
function arcSweep(a0, a1, am) {
|
|
57
|
+
const norm = (x) => {
|
|
58
|
+
let v = (x - a0) % (2 * Math.PI);
|
|
59
|
+
if (v < 0) v += 2 * Math.PI;
|
|
60
|
+
return v;
|
|
61
|
+
};
|
|
62
|
+
const m = norm(am);
|
|
63
|
+
const one = norm(a1);
|
|
64
|
+
return m <= one ? one : one - 2 * Math.PI;
|
|
65
|
+
}
|
|
14
66
|
function isLoopDoc(doc) {
|
|
15
67
|
return doc.loop === true || doc.endplates.length === 1;
|
|
16
68
|
}
|
|
@@ -290,9 +342,11 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
290
342
|
if (typeof e.widthInches === "number" && e.widthInches > 0)
|
|
291
343
|
endplateWidths[e.id] = e.widthInches;
|
|
292
344
|
}
|
|
293
|
-
const outline = (d.outline ?? []).filter(
|
|
294
|
-
|
|
295
|
-
|
|
345
|
+
const outline = (d.outline ?? []).filter((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y)).map((p) => ({
|
|
346
|
+
x: p.x,
|
|
347
|
+
y: p.y,
|
|
348
|
+
...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
|
|
349
|
+
}));
|
|
296
350
|
return {
|
|
297
351
|
lengthInches: len,
|
|
298
352
|
loop,
|
|
@@ -766,6 +820,6 @@ function poseOverridesFromDoc(doc) {
|
|
|
766
820
|
return out;
|
|
767
821
|
}
|
|
768
822
|
|
|
769
|
-
export { FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_SCALE_RATIO, asModuleSchematic, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, scaleFeetToInches, stateToDoc };
|
|
823
|
+
export { FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_SCALE_RATIO, asModuleSchematic, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, scaleFeetToInches, stateToDoc };
|
|
770
824
|
//# sourceMappingURL=index.js.map
|
|
771
825
|
//# sourceMappingURL=index.js.map
|