Files
git.stella-ops.org/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.TerminalClosures.cs

150 lines
5.8 KiB
C#

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;
}
}