Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions packages/viewer/src/client/renderers/sgcr/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -523,12 +523,14 @@ function assignCoordinates(
}

// FORCED-EDGE STRAIGHTENING: a node face holding exactly ONE wire has no sibling port to collide
// with, so that port can snap to the neighbour's port (when it falls on this face) and run straight
// — even when the mutual-spine pass above skipped the edge because a back-edge/sibling claimed the
// node's primary spine (e.g. a fork child whose parent's centre column is taken by a reversed back
// edge: its in/out edges would otherwise jog by a few px). Pass-through nodes (1 in / 1 out) get
// both edges straightened. Deterministic (id-sorted); a single-wire face can't create a within-face
// port collision (P5), and the snapped column is one the neighbour already occupies.
// with, so that port snaps toward the neighbour's port — CLAMPED to this node's face — and runs
// straight. This catches edges the mutual-spine pass skipped (a fork child whose parent's centre is
// claimed by a sibling/back-edge), AND the boundary case where the neighbour's port lands a hair
// outside this (narrower / ½-grid-parity-shifted) face: clamping snaps to the nearest on-face point
// (≤ the parity offset away) instead of leaving the full diagonal jog. Pass-through nodes (1 in /
// 1 out) get both edges straightened. Deterministic (id-sorted); a single-wire face can't create a
// within-face port collision (P5), so the snap is always safe.
const PARITY_SLACK = 1; // the ½-grid parity (0.5) + rounding can push a reachable neighbour port a hair past a narrower face
for (const it of [...items.values()].sort((p, q) => (p.id < q.id ? -1 : p.id > q.id ? 1 : 0))) {
if (it.isDummy || selfLoopCount.get(it.id)) continue;
const lo = it.cc - it.crossSize / 2 + o.portInset, hi = it.cc + it.crossSize / 2 - o.portInset;
Expand All @@ -539,8 +541,8 @@ function assignCoordinates(
const otherId = w.aItem === it.id ? w.bItem : w.aItem;
if (items.get(otherId)!.isDummy) continue; // keep long-edge chains on their routed columns
const np = portOf(w, otherId); // neighbour's port on its own face
if (np < lo - 1e-6 || np > hi + 1e-6) continue; // not reachable on this face → genuinely off to the side
setPort(w, it.id, Math.round(np));
if (np < lo - PARITY_SLACK || np > hi + PARITY_SLACK) continue; // genuinely off to the side → it must turn
setPort(w, it.id, Math.round(Math.max(lo, Math.min(hi, np)))); // reachable (or a parity-hair outside) → snap, clamped to face
}
}

Expand Down
Loading