Improve tie-net heuristics and destructive edit safeguards
This commit is contained in:
parent
31d2182258
commit
f65e4d9876
@ -1633,7 +1633,7 @@ async function compileModel(model, opts = {}) {
|
||||
|
||||
const m = result.layout_metrics;
|
||||
setStatus(
|
||||
`Compiled (${result.errors.length}E, ${result.warnings.length}W | ${m.crossings} crossings, ${m.overlap_edges} overlaps, ${m.total_bends ?? 0} bends, ${(m.detour_ratio ?? 1).toFixed(2)}x detour)`
|
||||
`Compiled (${result.errors.length}E, ${result.warnings.length}W | ${m.crossings} crossings, ${m.overlap_edges} overlaps, ${m.total_bends ?? 0} bends, ${m.label_tie_routes ?? 0} tie-nets, ${(m.detour_ratio ?? 1).toFixed(2)}x detour)`
|
||||
);
|
||||
} catch (err) {
|
||||
setStatus(`Compile failed: ${err.message}`, false);
|
||||
@ -2120,7 +2120,7 @@ async function runLayoutAction(path) {
|
||||
fitView(out.compile.layout);
|
||||
saveSnapshot();
|
||||
setStatus(
|
||||
`Compiled (${out.compile.errors.length}E, ${out.compile.warnings.length}W | ${out.compile.layout_metrics.crossings} crossings, ${out.compile.layout_metrics.overlap_edges} overlaps, ${out.compile.layout_metrics.total_bends ?? 0} bends)`
|
||||
`Compiled (${out.compile.errors.length}E, ${out.compile.warnings.length}W | ${out.compile.layout_metrics.crossings} crossings, ${out.compile.layout_metrics.overlap_edges} overlaps, ${out.compile.layout_metrics.total_bends ?? 0} bends, ${out.compile.layout_metrics.label_tie_routes ?? 0} tie-nets)`
|
||||
);
|
||||
} catch (err) {
|
||||
setStatus(`Layout action failed: ${err.message}`, false);
|
||||
|
||||
@ -260,7 +260,8 @@ export function compile(payload, options = {}) {
|
||||
total_length: 0,
|
||||
direct_length: 0,
|
||||
detour_ratio: 1,
|
||||
label_tie_fallbacks: 0
|
||||
label_tie_fallbacks: 0,
|
||||
label_tie_routes: 0
|
||||
},
|
||||
bus_groups: [],
|
||||
focus_map: {},
|
||||
|
||||
@ -1366,6 +1366,15 @@ function detectBusGroups(nets) {
|
||||
}
|
||||
|
||||
function shouldUseLabelTie(net, pinNodes, context) {
|
||||
if (!pinNodes.length) {
|
||||
return false;
|
||||
}
|
||||
const minX = Math.min(...pinNodes.map((p) => p.exit.x), 0);
|
||||
const maxX = Math.max(...pinNodes.map((p) => p.exit.x), 0);
|
||||
const minY = Math.min(...pinNodes.map((p) => p.exit.y), 0);
|
||||
const maxY = Math.max(...pinNodes.map((p) => p.exit.y), 0);
|
||||
const span = Math.abs(maxX - minX) + Math.abs(maxY - minY);
|
||||
|
||||
if (context.renderMode === "explicit") {
|
||||
return LABEL_TIE_CLASSES.has(net.class) && pinNodes.length > 2;
|
||||
}
|
||||
@ -1378,6 +1387,16 @@ function shouldUseLabelTie(net, pinNodes, context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prefer readable schematic stubs for dense multi-node nets.
|
||||
if (pinNodes.length >= 5) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Long-distributed analog/signal nets become noisy when fully routed.
|
||||
if ((net.class === "analog" || net.class === "signal") && pinNodes.length >= 3 && span > GRID * 56) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1577,6 +1596,7 @@ function computeLayoutMetrics(routed, busGroups) {
|
||||
(total, rn) => total + (rn.route_stats?.used_label_tie && rn.route_stats?.fallback_reason ? 1 : 0),
|
||||
0
|
||||
);
|
||||
const labelTieRoutes = routed.reduce((total, rn) => total + (rn.route_stats?.used_label_tie ? 1 : 0), 0);
|
||||
|
||||
return {
|
||||
segment_count: segmentCount,
|
||||
@ -1589,7 +1609,8 @@ function computeLayoutMetrics(routed, busGroups) {
|
||||
total_length: totalLength,
|
||||
direct_length: totalDirect,
|
||||
detour_ratio: totalDirect > 0 ? totalLength / totalDirect : 1,
|
||||
label_tie_fallbacks: labelTieFallbacks
|
||||
label_tie_fallbacks: labelTieFallbacks,
|
||||
label_tie_routes: labelTieRoutes
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ test("compile returns svg and topology for valid model", () => {
|
||||
assert.equal(typeof result.layout_metrics.total_bends, "number");
|
||||
assert.equal(typeof result.layout_metrics.detour_ratio, "number");
|
||||
assert.equal(typeof result.layout_metrics.label_tie_fallbacks, "number");
|
||||
assert.equal(typeof result.layout_metrics.label_tie_routes, "number");
|
||||
assert.ok(Array.isArray(result.bus_groups));
|
||||
assert.ok(result.render_mode_used);
|
||||
});
|
||||
@ -26,6 +27,7 @@ test("compile fails on invalid model", () => {
|
||||
assert.ok(result.errors.length > 0);
|
||||
assert.equal(result.layout_metrics.total_bends, 0);
|
||||
assert.equal(result.layout_metrics.detour_ratio, 1);
|
||||
assert.equal(result.layout_metrics.label_tie_routes, 0);
|
||||
});
|
||||
|
||||
test("compile accepts render mode options", () => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user