Refactor ElkSharp hybrid routing and document speed path
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
namespace StellaOps.ElkSharp;
|
||||
|
||||
internal static partial class ElkEdgeRouterIterative
|
||||
{
|
||||
private static ElkRoutedEdge[] ApplyTerminalRuleCleanupRound(
|
||||
ElkRoutedEdge[] edges,
|
||||
ElkPositionedNode[] nodes,
|
||||
ElkLayoutDirection direction,
|
||||
double minLineClearance,
|
||||
IReadOnlyCollection<string>? restrictedEdgeIds = null)
|
||||
{
|
||||
var result = edges;
|
||||
result = ElkEdgePostProcessor.SeparateSharedLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SeparateRepeatCollectorLocalLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.PreferShortestBoundaryShortcuts(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.NormalizeBoundaryAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.NormalizeSourceExitAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.ElevateRepeatCollectorNodeClearanceViolations(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkRepeatCollectorCorridors.SeparateSharedLanes(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadSourceDepartureJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SeparateMixedNodeFaceLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadTargetApproachJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadRectTargetApproachFeederBands(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.FinalizeDecisionTargetEntries(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.FinalizeGatewayBoundaryGeometry(result, nodes, restrictedEdgeIds);
|
||||
result = ClampBelowGraphEdges(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.AvoidNodeCrossings(result, nodes, direction, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.NormalizeBoundaryAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.NormalizeSourceExitAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.SeparateSharedLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadSourceDepartureJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadTargetApproachJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.FinalizeGatewayBoundaryGeometry(result, nodes, restrictedEdgeIds);
|
||||
result = ClampBelowGraphEdges(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.AvoidNodeCrossings(result, nodes, direction, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.NormalizeBoundaryAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.NormalizeSourceExitAngles(result, nodes);
|
||||
// Final late-stage verification: source/target boundary normalization can collapse
|
||||
// lanes back onto the same node face, so restabilize the local geometry once more.
|
||||
result = ElkEdgePostProcessor.SpreadSourceDepartureJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SeparateMixedNodeFaceLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadTargetApproachJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadRectTargetApproachFeederBands(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SeparateSharedLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ClampBelowGraphEdges(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.AvoidNodeCrossings(result, nodes, direction, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.NormalizeBoundaryAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.NormalizeSourceExitAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.SpreadSourceDepartureJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SeparateMixedNodeFaceLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadTargetApproachJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadRectTargetApproachFeederBands(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SeparateSharedLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.NormalizeBoundaryAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.NormalizeSourceExitAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadTargetApproachJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SeparateMixedNodeFaceLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SeparateSharedLaneConflicts(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.ElevateRepeatCollectorNodeClearanceViolations(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.ElevateUnderNodeViolations(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.PreferShortestBoundaryShortcuts(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadTargetApproachJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadRectTargetApproachFeederBands(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.ElevateUnderNodeViolations(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.FinalizeGatewayBoundaryGeometry(result, nodes, restrictedEdgeIds);
|
||||
result = ClampBelowGraphEdges(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.AvoidNodeCrossings(result, nodes, direction, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.NormalizeBoundaryAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.NormalizeSourceExitAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadTargetApproachJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadRectTargetApproachFeederBands(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.ElevateUnderNodeViolations(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.NormalizeBoundaryAngles(result, nodes);
|
||||
// Final hard-rule restabilization after the last normalize pass: the final
|
||||
// boundary normalization can still pull target slots and horizontal lanes back
|
||||
// into a bad state, so re-apply the local rule fixers once more before scoring.
|
||||
result = ElkEdgePostProcessor.NormalizeSourceExitAngles(result, nodes);
|
||||
result = ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadTargetApproachJoins(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SpreadRectTargetApproachFeederBands(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.ElevateRepeatCollectorNodeClearanceViolations(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.ElevateUnderNodeViolations(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ClampBelowGraphEdges(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.AvoidNodeCrossings(result, nodes, direction, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.NormalizeBoundaryAngles(result, nodes);
|
||||
result = CloseRemainingTerminalViolations(result, nodes, direction, minLineClearance, restrictedEdgeIds);
|
||||
var lateDetourShortcuts = ElkEdgePostProcessor.PreferShortestBoundaryShortcuts(result, nodes, restrictedEdgeIds);
|
||||
result = ElkEdgeRoutingScoring.CountBoundarySlotViolations(result, nodes) > 0
|
||||
? ChoosePreferredBoundarySlotRepairLayout(result, lateDetourShortcuts, nodes)
|
||||
: ChoosePreferredHardRuleLayout(result, lateDetourShortcuts, nodes);
|
||||
result = ApplyFinalDetourPolish(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SnapBoundarySlotAssignments(
|
||||
result,
|
||||
nodes,
|
||||
minLineClearance,
|
||||
restrictedEdgeIds,
|
||||
enforceAllNodeEndpoints: true);
|
||||
result = ApplyPostSlotDetourClosure(result, nodes, minLineClearance, restrictedEdgeIds);
|
||||
result = ElkEdgePostProcessor.SnapBoundarySlotAssignments(
|
||||
result,
|
||||
nodes,
|
||||
minLineClearance,
|
||||
restrictedEdgeIds,
|
||||
enforceAllNodeEndpoints: true);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user