@willcgage/module-schematic 0.109.0 → 0.110.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 +63 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +63 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3149,8 +3149,12 @@ function graphToDoc(pieces, input) {
|
|
|
3149
3149
|
for (const t of tracks) {
|
|
3150
3150
|
if (t.role === "main") continue;
|
|
3151
3151
|
const ends = turnouts.filter((sw) => sw.divergeTrack === t.id);
|
|
3152
|
-
if (ends.length >= 2 && new Set(ends.map((sw) => sw.onTrack)).size >= 2)
|
|
3153
|
-
|
|
3152
|
+
if (!(ends.length >= 2 && new Set(ends.map((sw) => sw.onTrack)).size >= 2)) continue;
|
|
3153
|
+
t.role = "crossover";
|
|
3154
|
+
const at = ends.map((sw) => sw.pos);
|
|
3155
|
+
t.fromPos = round(Math.min(...at));
|
|
3156
|
+
t.toPos = round(Math.max(...at));
|
|
3157
|
+
t.lane = main2Lane || 1;
|
|
3154
3158
|
}
|
|
3155
3159
|
const place = (a, what) => {
|
|
3156
3160
|
if (!a) return null;
|
|
@@ -3417,7 +3421,12 @@ function docToGraph(doc, answers = {}, library = BUILT_IN_TRACK_PARTS) {
|
|
|
3417
3421
|
const ends = [branch?.fromPos, branch?.toPos].filter(
|
|
3418
3422
|
(n) => typeof n === "number" && Number.isFinite(n)
|
|
3419
3423
|
);
|
|
3420
|
-
const divergeFarPos =
|
|
3424
|
+
const divergeFarPos = (
|
|
3425
|
+
// ⭐ A crossover half diverges TOWARD its partner. Its diverging track is a
|
|
3426
|
+
// MAIN, whose ends are the whole module, so the ordinary rule has nothing
|
|
3427
|
+
// useful to sign and would point it away from the turnout it feeds.
|
|
3428
|
+
divergeFarOverride.get(t.id) ?? (ends.length ? ends.reduce((a, b) => Math.abs(b - t.pos) > Math.abs(a - t.pos) ? b : a) : void 0)
|
|
3429
|
+
);
|
|
3421
3430
|
const facing = turnoutFacing({
|
|
3422
3431
|
pos: t.pos,
|
|
3423
3432
|
divergeFarPos,
|
|
@@ -3534,6 +3543,7 @@ function docToGraph(doc, answers = {}, library = BUILT_IN_TRACK_PARTS) {
|
|
|
3534
3543
|
fromPos: a.x0,
|
|
3535
3544
|
toPos: a.x0 + a.geom.lengthInches
|
|
3536
3545
|
}));
|
|
3546
|
+
const mainIdsAll = new Set(mains.map((m) => m.id));
|
|
3537
3547
|
const attachment = /* @__PURE__ */ new Map();
|
|
3538
3548
|
for (const t of turnouts) {
|
|
3539
3549
|
const m = mains.find((x) => x.id === t.divergeTrack && x.id !== main.id);
|
|
@@ -3542,11 +3552,27 @@ function docToGraph(doc, answers = {}, library = BUILT_IN_TRACK_PARTS) {
|
|
|
3542
3552
|
const to = m.toPos ?? mainLen;
|
|
3543
3553
|
if (from > 0 && Math.abs(t.pos - from) < 0.01) attachment.set(m.id, { sw: t, at: "from" });
|
|
3544
3554
|
else if (Math.abs(t.pos - to) < 0.01) attachment.set(m.id, { sw: t, at: "to" });
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3555
|
+
}
|
|
3556
|
+
const mainToMainPairs = [];
|
|
3557
|
+
{
|
|
3558
|
+
const isMain = (id) => mainIdsAll.has(id);
|
|
3559
|
+
const used = /* @__PURE__ */ new Set();
|
|
3560
|
+
for (const t of turnouts) {
|
|
3561
|
+
if (used.has(t.id) || !isMain(t.onTrack) || !isMain(t.divergeTrack)) continue;
|
|
3562
|
+
if (t.onTrack === t.divergeTrack) continue;
|
|
3563
|
+
const partner = turnouts.filter(
|
|
3564
|
+
(u) => !used.has(u.id) && u.id !== t.id && u.onTrack === t.divergeTrack && u.divergeTrack === t.onTrack
|
|
3565
|
+
).sort((x, y) => Math.abs(x.pos - t.pos) - Math.abs(y.pos - t.pos))[0];
|
|
3566
|
+
if (!partner) continue;
|
|
3567
|
+
used.add(t.id);
|
|
3568
|
+
used.add(partner.id);
|
|
3569
|
+
mainToMainPairs.push({ a: t, b: partner });
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3572
|
+
const divergeFarOverride = /* @__PURE__ */ new Map();
|
|
3573
|
+
for (const { a, b } of mainToMainPairs) {
|
|
3574
|
+
divergeFarOverride.set(a.id, b.pos);
|
|
3575
|
+
divergeFarOverride.set(b.id, a.pos);
|
|
3550
3576
|
}
|
|
3551
3577
|
for (const m of mains) {
|
|
3552
3578
|
if (attachment.get(m.id)?.at === "from") continue;
|
|
@@ -3601,6 +3627,35 @@ function docToGraph(doc, answers = {}, library = BUILT_IN_TRACK_PARTS) {
|
|
|
3601
3627
|
done.add(m.id);
|
|
3602
3628
|
}
|
|
3603
3629
|
for (const id of assemblyTracks) done.add(id);
|
|
3630
|
+
for (const [i, pair] of mainToMainPairs.entries()) {
|
|
3631
|
+
const la = laidTurnouts.get(pair.a.id);
|
|
3632
|
+
const lb = laidTurnouts.get(pair.b.id);
|
|
3633
|
+
if (!la || !lb) continue;
|
|
3634
|
+
const ja = jointAt(la.piece, la.divergeId);
|
|
3635
|
+
const jb = jointAt(lb.piece, lb.divergeId);
|
|
3636
|
+
if (!ja || !jb) continue;
|
|
3637
|
+
const dx = jb.x - ja.x;
|
|
3638
|
+
const dy = jb.y - ja.y;
|
|
3639
|
+
const len = Math.hypot(dx, dy);
|
|
3640
|
+
if (!(len > 1e-6)) {
|
|
3641
|
+
notLaid.push({
|
|
3642
|
+
id: pair.a.divergeTrack,
|
|
3643
|
+
why: `${pair.a.name || pair.a.id} and ${pair.b.name || pair.b.id} meet at the same point, so there is no track between them to lay`
|
|
3644
|
+
});
|
|
3645
|
+
continue;
|
|
3646
|
+
}
|
|
3647
|
+
pieces.push({
|
|
3648
|
+
id: `xc-${i}`,
|
|
3649
|
+
partId: flexId,
|
|
3650
|
+
x: ja.x,
|
|
3651
|
+
y: ja.y,
|
|
3652
|
+
rotationDeg: Math.atan2(dy, dx) * 180 / Math.PI,
|
|
3653
|
+
lengthInches: r3(len)
|
|
3654
|
+
});
|
|
3655
|
+
warnings.push(
|
|
3656
|
+
`${pair.a.name || pair.a.id} and ${pair.b.name || pair.b.id} are laid as two separate turnouts with a ${len.toFixed(1)}\u2033 piece of track between them, which is what the document describes. If they are really one crossover assembly, name the product on a connector track and it will be laid as the single piece it is.`
|
|
3657
|
+
);
|
|
3658
|
+
}
|
|
3604
3659
|
let progressed = true;
|
|
3605
3660
|
while (progressed) {
|
|
3606
3661
|
progressed = false;
|