Refactor ElkSharp hybrid routing and document speed path
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace StellaOps.ElkSharp;
|
||||
|
||||
internal static partial class ElkEdgeRouterIterative
|
||||
{
|
||||
private static bool ShouldPreferFastTerminalOnlyHardRuleClosure(RoutingRetryState retryState)
|
||||
{
|
||||
return retryState.RemainingShortHighways == 0
|
||||
&& retryState.RepeatCollectorCorridorViolations == 0
|
||||
&& retryState.RepeatCollectorNodeClearanceViolations == 0
|
||||
&& retryState.TargetApproachBacktrackingViolations == 0
|
||||
&& retryState.ExcessiveDetourViolations == 0
|
||||
&& retryState.BoundarySlotViolations == 0
|
||||
&& retryState.BelowGraphViolations == 0
|
||||
&& retryState.UnderNodeViolations == 0
|
||||
&& retryState.LongDiagonalViolations == 0
|
||||
&& retryState.SharedLaneViolations <= 2
|
||||
&& (retryState.TargetApproachJoinViolations > 0
|
||||
|| retryState.EntryAngleViolations > 0
|
||||
|| retryState.GatewaySourceExitViolations > 0
|
||||
|| retryState.SharedLaneViolations > 0);
|
||||
}
|
||||
|
||||
private static ElkRoutedEdge[] BuildFastTerminalOnlyHardRuleCandidate(
|
||||
ElkRoutedEdge[] edges,
|
||||
ElkPositionedNode[] nodes,
|
||||
ElkLayoutDirection direction,
|
||||
double minLineClearance,
|
||||
IReadOnlyCollection<string> restrictedEdgeIds)
|
||||
{
|
||||
var candidate = edges;
|
||||
candidate = ChoosePreferredHardRuleLayout(
|
||||
candidate,
|
||||
ElkEdgePostProcessor.SeparateSharedLaneConflicts(
|
||||
candidate,
|
||||
nodes,
|
||||
minLineClearance,
|
||||
restrictedEdgeIds),
|
||||
nodes);
|
||||
candidate = ChoosePreferredHardRuleLayout(
|
||||
candidate,
|
||||
ElkEdgePostProcessor.SpreadSourceDepartureJoins(
|
||||
candidate,
|
||||
nodes,
|
||||
minLineClearance,
|
||||
restrictedEdgeIds),
|
||||
nodes);
|
||||
candidate = ChoosePreferredHardRuleLayout(
|
||||
candidate,
|
||||
ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(
|
||||
candidate,
|
||||
nodes,
|
||||
minLineClearance,
|
||||
restrictedEdgeIds),
|
||||
nodes);
|
||||
candidate = ChoosePreferredHardRuleLayout(
|
||||
candidate,
|
||||
ElkEdgePostProcessor.SpreadTargetApproachJoins(
|
||||
candidate,
|
||||
nodes,
|
||||
minLineClearance,
|
||||
restrictedEdgeIds,
|
||||
forceOutwardAxisSpacing: true),
|
||||
nodes);
|
||||
candidate = ChoosePreferredHardRuleLayout(
|
||||
candidate,
|
||||
ElkEdgePostProcessor.NormalizeBoundaryAngles(candidate, nodes),
|
||||
nodes);
|
||||
candidate = ChoosePreferredHardRuleLayout(
|
||||
candidate,
|
||||
ElkEdgePostProcessor.NormalizeSourceExitAngles(candidate, nodes),
|
||||
nodes);
|
||||
candidate = ChoosePreferredHardRuleLayout(
|
||||
candidate,
|
||||
ElkEdgePostProcessor.SeparateSharedLaneConflicts(
|
||||
candidate,
|
||||
nodes,
|
||||
minLineClearance,
|
||||
restrictedEdgeIds),
|
||||
nodes);
|
||||
return candidate;
|
||||
}
|
||||
|
||||
private static bool ShouldPreferCompactFocusedTerminalClosure(
|
||||
RoutingRetryState retryState,
|
||||
int focusEdgeCount)
|
||||
{
|
||||
return focusEdgeCount <= 4
|
||||
&& retryState.BoundarySlotViolations == 0
|
||||
&& retryState.BelowGraphViolations == 0
|
||||
&& retryState.UnderNodeViolations == 0
|
||||
&& retryState.GatewaySourceExitViolations == 0
|
||||
&& retryState.EntryAngleViolations == 0
|
||||
&& retryState.TargetApproachBacktrackingViolations == 0
|
||||
&& retryState.ExcessiveDetourViolations == 0
|
||||
&& retryState.TargetApproachJoinViolations <= 1
|
||||
&& retryState.SharedLaneViolations <= 1
|
||||
&& (retryState.TargetApproachJoinViolations > 0
|
||||
|| retryState.SharedLaneViolations > 0);
|
||||
}
|
||||
|
||||
private static ElkRoutedEdge[] ApplyCompactFocusedTerminalClosure(
|
||||
ElkRoutedEdge[] edges,
|
||||
ElkPositionedNode[] nodes,
|
||||
ElkLayoutDirection direction,
|
||||
double minLineClearance,
|
||||
IReadOnlyCollection<string> focusedEdgeIds)
|
||||
{
|
||||
var candidate = edges;
|
||||
candidate = ApplyGuardedFocusedHardRulePass(
|
||||
candidate,
|
||||
nodes,
|
||||
current => ElkEdgePostProcessor.SeparateSharedLaneConflicts(current, nodes, minLineClearance, focusedEdgeIds));
|
||||
candidate = ApplyGuardedFocusedHardRulePass(
|
||||
candidate,
|
||||
nodes,
|
||||
current => ElkEdgePostProcessor.SpreadSourceDepartureJoins(current, nodes, minLineClearance, focusedEdgeIds));
|
||||
candidate = ApplyGuardedFocusedHardRulePass(
|
||||
candidate,
|
||||
nodes,
|
||||
current => ElkEdgePostProcessor.RepairBoundaryAnglesAndTargetApproaches(current, nodes, minLineClearance, focusedEdgeIds));
|
||||
candidate = ApplyGuardedFocusedHardRulePass(
|
||||
candidate,
|
||||
nodes,
|
||||
current => ElkEdgePostProcessor.SpreadTargetApproachJoins(
|
||||
current,
|
||||
nodes,
|
||||
minLineClearance,
|
||||
focusedEdgeIds,
|
||||
forceOutwardAxisSpacing: true));
|
||||
candidate = ApplyGuardedFocusedHardRulePass(
|
||||
candidate,
|
||||
nodes,
|
||||
current => ElkEdgePostProcessor.SeparateSharedLaneConflicts(current, nodes, minLineClearance, focusedEdgeIds));
|
||||
candidate = ApplyGuardedFocusedHardRulePass(
|
||||
candidate,
|
||||
nodes,
|
||||
current => ElkEdgePostProcessor.NormalizeBoundaryAngles(current, nodes));
|
||||
candidate = ApplyGuardedFocusedHardRulePass(
|
||||
candidate,
|
||||
nodes,
|
||||
current => ElkEdgePostProcessor.NormalizeSourceExitAngles(current, nodes));
|
||||
return candidate;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user