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;
|
const m = result.layout_metrics;
|
||||||
setStatus(
|
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) {
|
} catch (err) {
|
||||||
setStatus(`Compile failed: ${err.message}`, false);
|
setStatus(`Compile failed: ${err.message}`, false);
|
||||||
@ -2120,7 +2120,7 @@ async function runLayoutAction(path) {
|
|||||||
fitView(out.compile.layout);
|
fitView(out.compile.layout);
|
||||||
saveSnapshot();
|
saveSnapshot();
|
||||||
setStatus(
|
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) {
|
} catch (err) {
|
||||||
setStatus(`Layout action failed: ${err.message}`, false);
|
setStatus(`Layout action failed: ${err.message}`, false);
|
||||||
|
|||||||
@ -260,7 +260,8 @@ export function compile(payload, options = {}) {
|
|||||||
total_length: 0,
|
total_length: 0,
|
||||||
direct_length: 0,
|
direct_length: 0,
|
||||||
detour_ratio: 1,
|
detour_ratio: 1,
|
||||||
label_tie_fallbacks: 0
|
label_tie_fallbacks: 0,
|
||||||
|
label_tie_routes: 0
|
||||||
},
|
},
|
||||||
bus_groups: [],
|
bus_groups: [],
|
||||||
focus_map: {},
|
focus_map: {},
|
||||||
|
|||||||
@ -1366,6 +1366,15 @@ function detectBusGroups(nets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function shouldUseLabelTie(net, pinNodes, context) {
|
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") {
|
if (context.renderMode === "explicit") {
|
||||||
return LABEL_TIE_CLASSES.has(net.class) && pinNodes.length > 2;
|
return LABEL_TIE_CLASSES.has(net.class) && pinNodes.length > 2;
|
||||||
}
|
}
|
||||||
@ -1378,6 +1387,16 @@ function shouldUseLabelTie(net, pinNodes, context) {
|
|||||||
return true;
|
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;
|
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),
|
(total, rn) => total + (rn.route_stats?.used_label_tie && rn.route_stats?.fallback_reason ? 1 : 0),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
const labelTieRoutes = routed.reduce((total, rn) => total + (rn.route_stats?.used_label_tie ? 1 : 0), 0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
segment_count: segmentCount,
|
segment_count: segmentCount,
|
||||||
@ -1589,7 +1609,8 @@ function computeLayoutMetrics(routed, busGroups) {
|
|||||||
total_length: totalLength,
|
total_length: totalLength,
|
||||||
direct_length: totalDirect,
|
direct_length: totalDirect,
|
||||||
detour_ratio: totalDirect > 0 ? totalLength / totalDirect : 1,
|
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.total_bends, "number");
|
||||||
assert.equal(typeof result.layout_metrics.detour_ratio, "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_fallbacks, "number");
|
||||||
|
assert.equal(typeof result.layout_metrics.label_tie_routes, "number");
|
||||||
assert.ok(Array.isArray(result.bus_groups));
|
assert.ok(Array.isArray(result.bus_groups));
|
||||||
assert.ok(result.render_mode_used);
|
assert.ok(result.render_mode_used);
|
||||||
});
|
});
|
||||||
@ -26,6 +27,7 @@ test("compile fails on invalid model", () => {
|
|||||||
assert.ok(result.errors.length > 0);
|
assert.ok(result.errors.length > 0);
|
||||||
assert.equal(result.layout_metrics.total_bends, 0);
|
assert.equal(result.layout_metrics.total_bends, 0);
|
||||||
assert.equal(result.layout_metrics.detour_ratio, 1);
|
assert.equal(result.layout_metrics.detour_ratio, 1);
|
||||||
|
assert.equal(result.layout_metrics.label_tie_routes, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("compile accepts render mode options", () => {
|
test("compile accepts render mode options", () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user