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