From a0219dc30826fb2813c831bab6699b7aa63c4237 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Wed, 19 Aug 2026 10:04:52 +0200 Subject: [PATCH] [WIP] PipeJoins --- PamhagenSysCtrl/Helpers/PamhagenGraph.cs | 8 +- PamhagenSysCtrl/Helpers/Pipeline/PipeJoin.cs | 103 ++++++++++++------- 2 files changed, 70 insertions(+), 41 deletions(-) diff --git a/PamhagenSysCtrl/Helpers/PamhagenGraph.cs b/PamhagenSysCtrl/Helpers/PamhagenGraph.cs index 604c8a5..014b02d 100644 --- a/PamhagenSysCtrl/Helpers/PamhagenGraph.cs +++ b/PamhagenSysCtrl/Helpers/PamhagenGraph.cs @@ -512,6 +512,7 @@ namespace PamhagenSysCtrl.Helpers { HashSet visited = []; foreach (var (edge, node) in path.Hops) { edge.Highlight = color1; + (edge.Start as PipeJoin)?.Highlight = color1; if (flowArrows > MotorState.Halt) { var dir = edge.End == node; if (flowArrows == MotorState.Backward) dir = !dir; @@ -520,7 +521,10 @@ namespace PamhagenSysCtrl.Helpers { } visited.Add(edge); if (node is Pump) color = color2; - TraverseSubgraph(node, (n) => n is Valve || n is ISink || n is Pump, visited, edgeAction: (s, r, e) => e.Highlight = color); + TraverseSubgraph(node, (n) => n is Valve || n is ISink || n is Pump, visited, edgeAction: (s, r, e) => { + (s as PipeJoin)?.Highlight = color; + e.Highlight = color; + }); } } @@ -530,6 +534,8 @@ namespace PamhagenSysCtrl.Helpers { edgeAction: (s, r, e) => { if (((e.Start as Valve)?.IsOpen ?? true) && ((e.End as Valve)?.IsOpen ?? true)) { e.Highlight = color1; + (e.Start as PipeJoin)?.Highlight = color1; + (e.End as PipeJoin)?.Highlight = color1; if (flowArrows == MotorState.Forward || flowArrows == MotorState.Backward) { var dir = e.Start == s; if (r) dir = !dir; diff --git a/PamhagenSysCtrl/Helpers/Pipeline/PipeJoin.cs b/PamhagenSysCtrl/Helpers/Pipeline/PipeJoin.cs index 0ad6998..d16e02e 100644 --- a/PamhagenSysCtrl/Helpers/Pipeline/PipeJoin.cs +++ b/PamhagenSysCtrl/Helpers/Pipeline/PipeJoin.cs @@ -1,7 +1,6 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Media; -using System.Windows.Shapes; namespace PamhagenSysCtrl.Helpers.Pipeline { public class PipeJoin : INode { @@ -12,11 +11,12 @@ namespace PamhagenSysCtrl.Helpers.Pipeline { public double CenterX { get; set; } public double CenterY { get; set; } public string Label => ""; + public Brush? Highlight { get; set; } public ISet Inputs { get; init; } public ISet Outputs { get; init; } - private Polygon? _rect; + private System.Windows.Shapes.Path? _rect; public PipeJoin(double x, double y) { CenterX = x; @@ -26,8 +26,8 @@ namespace PamhagenSysCtrl.Helpers.Pipeline { } public void Draw(Canvas canvas) { - _rect = new Polygon() { - Fill = Brushes.Black, + _rect = new System.Windows.Shapes.Path() { + Fill = Brushes.DarkGray, Stroke = Brushes.Black, }; canvas.Children.Add(_rect); @@ -43,43 +43,66 @@ namespace PamhagenSysCtrl.Helpers.Pipeline { var il = Inputs.Any(e => (e.Start.CenterX < CenterX && (e.Orientation || e.Start.CenterY == CenterY)) || (e.IsTwoWay && e.End.CenterX < CenterX && (e.Orientation || e.End.CenterY == CenterY))); var ol = Outputs.Any(e => (e.End.CenterX < CenterX && (!e.Orientation || e.End.CenterY == CenterY)) || (e.IsTwoWay && e.Start.CenterX < CenterX && (!e.Orientation || e.Start.CenterY == CenterY))); - var points = new List { - new(0, 0) - }; - if (ot && it) { - points.AddRange([new(SIZE / 2 - POINT, 0), new(SIZE / 2, -POINT / 2), new(SIZE / 2, POINT / 2), new(SIZE / 2 + POINT, 0)]); - } else if (ot) { - points.AddRange([new(SIZE / 2 - POINT, 0), new(SIZE / 2, -POINT), new(SIZE / 2 + POINT, 0)]); - } else if (it) { - points.AddRange([new(SIZE / 2 - POINT, 0), new(SIZE / 2, POINT), new(SIZE / 2 + POINT, 0)]); - } - points.Add(new(SIZE, 0)); - if (or && ir) { - points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE + POINT / 2, SIZE / 2), new(SIZE - POINT / 2, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); - } else if (or) { - points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE + POINT, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); - } else if (ir) { - points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE - POINT, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); - } - points.Add(new(SIZE, SIZE)); - if (ob && ib) { - points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE + POINT / 2), new(SIZE / 2, SIZE - POINT / 2), new(SIZE / 2 - POINT, SIZE)]); - } else if (ob) { - points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE + POINT), new(SIZE / 2 - POINT, SIZE)]); - } else if (ib) { - points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE - POINT), new(SIZE / 2 - POINT, SIZE)]); - } - points.Add(new(0, SIZE)); - if (ol && il) { - points.AddRange([new(0, SIZE / 2 + POINT), new(-POINT / 2, SIZE / 2), new(POINT / 2, SIZE / 2), new(0, SIZE / 2 - POINT)]); - } else if (ol) { - points.AddRange([new(0, SIZE / 2 + POINT), new(-POINT, SIZE / 2), new(0, SIZE / 2 - POINT)]); - } else if (il) { - points.AddRange([new(0, SIZE / 2 + POINT), new(POINT, SIZE / 2), new(0, SIZE / 2 - POINT)]); + var size = new Size(SIZE / 2 * scale, SIZE / 2 * scale); + var geo = new StreamGeometry(); + using (var ctx = geo.Open()) { + var points = new List { + new(0, 0) + }; + + ctx.BeginFigure(new((SIZE / 2 - POINT) * scale, 0), true, false); + if (ot && it) { + points.AddRange([new(SIZE / 2, -POINT / 2), new(SIZE / 2, POINT / 2), new(SIZE / 2 + POINT, 0)]); + } else if (ot) { + ctx.PolyLineTo([new(SIZE / 2 * scale, -POINT * scale), new((SIZE / 2 + POINT) * scale, 0)], true, false); + } else if (it) { + ctx.PolyLineTo([new(SIZE / 2 * scale, POINT * scale), new((SIZE / 2 + POINT) * scale, 0)], true, false); + } else { + ctx.ArcTo(new((SIZE / 2 + POINT) * scale, 0), size, 0, false, SweepDirection.Clockwise, true, false); + } + + ctx.ArcTo(new(SIZE * scale, (SIZE / 2 - POINT) * scale), size, 0, false, SweepDirection.Clockwise, true, false); + points.Add(new(SIZE, 0)); + if (or && ir) { + points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE + POINT / 2, SIZE / 2), new(SIZE - POINT / 2, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); + } else if (or) { + ctx.PolyLineTo([new((SIZE + POINT) * scale, SIZE / 2 * scale), new(SIZE * scale, (SIZE / 2 + POINT) * scale)], true, false); + } else if (ir) { + ctx.PolyLineTo([new((SIZE - POINT) * scale, SIZE / 2 * scale), new(SIZE * scale, (SIZE / 2 + POINT) * scale)], true, false); + } else { + ctx.ArcTo(new(SIZE * scale, (SIZE / 2 + POINT) * scale), size, 0, false, SweepDirection.Clockwise, true, false); + } + + ctx.ArcTo(new((SIZE / 2 + POINT) * scale, SIZE * scale), size, 0, false, SweepDirection.Clockwise, true, false); + points.Add(new(SIZE, SIZE)); + if (ob && ib) { + points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE + POINT / 2), new(SIZE / 2, SIZE - POINT / 2), new(SIZE / 2 - POINT, SIZE)]); + } else if (ob) { + ctx.PolyLineTo([new(SIZE / 2 * scale, (SIZE + POINT) * scale), new((SIZE / 2 - POINT) * scale, SIZE * scale)], true, false); + } else if (ib) { + ctx.PolyLineTo([new(SIZE / 2 * scale, (SIZE - POINT) * scale), new((SIZE / 2 - POINT) * scale, SIZE * scale)], true, false); + } else { + ctx.ArcTo(new((SIZE / 2 - POINT) * scale, SIZE * scale), size, 0, false, SweepDirection.Clockwise, true, false); + } + + ctx.ArcTo(new(0, (SIZE / 2 + POINT) * scale), size, 0, false, SweepDirection.Clockwise, true, false); + points.Add(new(0, SIZE)); + if (ol && il) { + points.AddRange([new(0, SIZE / 2 + POINT), new(-POINT / 2, SIZE / 2), new(POINT / 2, SIZE / 2), new(0, SIZE / 2 - POINT)]); + } else if (ol) { + ctx.PolyLineTo([new(-POINT * scale, SIZE / 2 * scale), new(0, (SIZE / 2 - POINT) * scale)], true, false); + } else if (il) { + ctx.PolyLineTo([new(POINT * scale, SIZE / 2 * scale), new(0, (SIZE / 2 - POINT) * scale)], true, false); + } else { + ctx.ArcTo(new(0, (SIZE / 2 - POINT) * scale), size, 0, false, SweepDirection.Clockwise, true, false); + } + + ctx.ArcTo(new((SIZE / 2 - POINT) * scale, 0), size, 0, false, SweepDirection.Clockwise, true, false); } - _rect?.Points = [.. points.Select(p => new Point(p.X * scale, p.Y * scale))]; - _rect?.StrokeThickness = 2; + _rect?.Data = geo; + // [.. points.Select(p => new Point(p.X * scale, p.Y * scale))]; + _rect?.StrokeThickness = Graph.ToBorder(scale); _rect?.SetValue(Canvas.LeftProperty, (CenterX - SIZE / 2) * scale); _rect?.SetValue(Canvas.TopProperty, (CenterY - SIZE / 2) * scale); } @@ -89,7 +112,7 @@ namespace PamhagenSysCtrl.Helpers.Pipeline { } public void Update(bool isHovering, bool isPressed) { - _rect?.Stroke = isHovering ? Brushes.Black : Brushes.Black; + _rect?.Fill = Highlight ?? Brushes.DarkGray; } } }