using HelixToolkit.Wpf; namespace Yw.WpfUI.Hydro { /// /// 抽象编辑管理器 /// internal class LogicalEditManager : LogicalManager { /// /// /// public LogicalEditManager(HelixViewport3D viewport) : base(viewport) { } private eLogicalEditMode _logicalMode = eLogicalEditMode.None;//编辑模式 private VisualL3d _visual = null;//可视化对象 #region 添加方法 /// /// 开始添加连接节点 /// public void StartAddJunction() { _logicalMode = eLogicalEditMode.AddJunction; } /// /// 开始添加水库 /// public void StartAddReservoir() { _logicalMode = eLogicalEditMode.AddReservoir; } /// /// 开始添加水池 /// public void StartAddTank() { _logicalMode = eLogicalEditMode.AddTank; } /// /// 开始添加自由管道 /// public void StartAddPipe() { _logicalMode = eLogicalEditMode.AddPipe; } /// /// 开始添加水平管道 /// public void StartAddHorizPipe() { _logicalMode = eLogicalEditMode.AddHorizPipe; } /// /// 开始添加垂直管道 /// public void StartAddVertPipe() { _logicalMode = eLogicalEditMode.AddVertPipe; } /// /// 开始添加水泵 /// public void StartAddPump() { _logicalMode = eLogicalEditMode.AddPump; } /// /// 开始添加阀门 /// public void StartAddValve() { _logicalMode = eLogicalEditMode.AddValve; } #endregion #region 重写事件 //鼠标按下 protected override void OnMouseDown(MouseButtonEventArgs e) { if (!Initialized) { return; } switch (_logicalMode) { case eLogicalEditMode.AddJunction: { var pt = e.GetPosition(_viewport); var sp = _viewport.Viewport.UnProject(pt); if (sp.HasValue) { var visual = new JunctionL3d(); visual.Id = Yw.Untity.UniqueHelper.CreateFromFirst("junction", _nw.Junctions.Select(x => x.Id).ToList()); visual.Position = sp.Value.ToPointL3d(); AddVisual(visual); _visual = visual; } } break; case eLogicalEditMode.AddReservoir: { var pt = e.GetPosition(_viewport); var sp = _viewport.Viewport.UnProject(pt); if (sp.HasValue) { var visual = new ReservoirL3d(); visual.Id = Yw.Untity.UniqueHelper.CreateFromFirst("reservoir", _nw.Reservoirs.Select(x => x.Id).ToList()); visual.Position = sp.Value.ToPointL3d(); AddVisual(visual); _visual = visual; } } break; case eLogicalEditMode.AddTank: { var pt = e.GetPosition(_viewport); var sp = _viewport.Viewport.UnProject(pt); if (sp.HasValue) { var visual = new TankL3d(); visual.Id = Yw.Untity.UniqueHelper.CreateFromFirst("tank", _nw.Reservoirs.Select(x => x.Id).ToList()); visual.Position = sp.Value.ToPointL3d(); AddVisual(visual); _visual = visual; } } break; case eLogicalEditMode.AddPipe: { var pt = e.GetPosition(_viewport); var logicalNode = SnapNearestNode(pt); if (logicalNode != null) { var visual = new PipeL3d(); visual.Id = Yw.Untity.UniqueHelper.CreateFromFirst("pipe", _nw.Pipes.Select(x => x.Id).ToList()); visual.StartPosition = logicalNode.Position.ToPointL3d(); visual.EndPosition = logicalNode.Position.ToPointL3d(); AddVisual(visual); _visual = visual; } } break; case eLogicalEditMode.AddHorizPipe: { var pt = e.GetPosition(_viewport); var logicalNode = SnapNearestNode(pt); if (logicalNode != null) { var visual = new PipeL3d(); visual.Id = Yw.Untity.UniqueHelper.CreateFromFirst("pipe", _nw.Pipes.Select(x => x.Id).ToList()); visual.StartPosition = logicalNode.Position.ToPointL3d(); visual.EndPosition = logicalNode.Position.ToPointL3d(); AddVisual(visual); _visual = visual; } } break; case eLogicalEditMode.AddVertPipe: { var pt = e.GetPosition(_viewport); var logicalNode = SnapNearestNode(pt); if (logicalNode != null) { var visual = new PipeL3d(); visual.Id = Yw.Untity.UniqueHelper.CreateFromFirst("pipe", _nw.Pipes.Select(x => x.Id).ToList()); visual.StartPosition = logicalNode.Position.ToPointL3d(); visual.EndPosition = logicalNode.Position.ToPointL3d(); AddVisual(visual); _visual = visual; } } break; case eLogicalEditMode.AddPump: { var pt = e.GetPosition(_viewport); var logicalNode = SnapNearestNode(pt); if (logicalNode != null) { var visual = new PumpL3d(); visual.Id = Yw.Untity.UniqueHelper.CreateFromFirst("pump", _nw.Pumps.Select(x => x.Id).ToList()); visual.StartPosition = logicalNode.Position.ToPointL3d(); visual.EndPosition = logicalNode.Position.ToPointL3d(); AddVisual(visual); _visual = visual; } } break; case eLogicalEditMode.AddValve: { var pt = e.GetPosition(_viewport); var logicalNode = SnapNearestNode(pt); if (logicalNode != null) { var visual = new ValveL3d(); visual.Id = Yw.Untity.UniqueHelper.CreateFromFirst("valve", _nw.Pumps.Select(x => x.Id).ToList()); visual.StartPosition = logicalNode.Position.ToPointL3d(); visual.EndPosition = logicalNode.Position.ToPointL3d(); AddVisual(visual); _visual = visual; } } break; default: { base.OnMouseDown(e); } break; } } //鼠标弹起 protected override void OnMouseUp(MouseButtonEventArgs e) { if (!Initialized) { return; } switch (_logicalMode) { case eLogicalEditMode.AddJunction: { _visual = null; _logicalMode = eLogicalEditMode.None; } break; case eLogicalEditMode.AddReservoir: { _visual = null; _logicalMode = eLogicalEditMode.None; } break; case eLogicalEditMode.AddTank: { _visual = null; _logicalMode = eLogicalEditMode.None; } break; case eLogicalEditMode.AddPipe: { var pt = e.GetPosition(_viewport); var logicalNode = SnapNearestNode(pt); if (logicalNode == null) { var sp = _viewport.Viewport.UnProject(pt); var junction = new JunctionL3d(); junction.Id = Yw.Untity.UniqueHelper.CreateFromFirst("junction", _nw.Junctions.Select(x => x.Id).ToList()); junction.Position = sp.Value.ToPointL3d(); AddVisual(junction); } else { var end = logicalNode.Position.ToPointL3d(); var pipe = _visual as PipeL3d; if (pipe != null) { pipe.EndPosition = end; UpdateVisual(pipe); } } _visual = null; _logicalMode = eLogicalEditMode.None; } break; case eLogicalEditMode.AddHorizPipe: { var pipe = _visual as PipeL3d; if (pipe != null) { var end = pipe.EndPosition.ToPoint3D(); var logicalNode = SnapNearestNode(end); if (logicalNode == null) { var junction = new JunctionL3d(); junction.Id = Yw.Untity.UniqueHelper.CreateFromFirst("junction", _nw.Junctions.Select(x => x.Id).ToList()); junction.Position = end.ToPointL3d(); AddVisual(junction); } } _visual = null; _logicalMode = eLogicalEditMode.None; } break; case eLogicalEditMode.AddVertPipe: { var pipe = _visual as PipeL3d; if (pipe != null) { var end = pipe.EndPosition.ToPoint3D(); LogicalNode3D logicalNode = SnapNearestNode(end); if (logicalNode == null) { var junction = new JunctionL3d(); junction.Id = Yw.Untity.UniqueHelper.CreateFromFirst("junction", _nw.Junctions.Select(x => x.Id).ToList()); junction.Position = end.ToPointL3d(); AddVisual(junction); } } _visual = null; _logicalMode = eLogicalEditMode.None; } break; case eLogicalEditMode.AddPump: { var pt = e.GetPosition(_viewport); var logicalNode = SnapNearestNode(pt); if (logicalNode == null) { var sp = _viewport.Viewport.UnProject(pt); var junction = new JunctionL3d(); junction.Id = Yw.Untity.UniqueHelper.CreateFromFirst("junction", _nw.Junctions.Select(x => x.Id).ToList()); junction.Position = sp.Value.ToPointL3d(); AddVisual(junction); } else { var end = logicalNode.Position.ToPointL3d(); var pump = _visual as PumpL3d; if (pump != null) { pump.EndPosition = end; UpdateVisual(pump); } } _visual = null; _logicalMode = eLogicalEditMode.None; } break; case eLogicalEditMode.AddValve: { var pt = e.GetPosition(_viewport); var logicalNode = SnapNearestNode(pt); if (logicalNode == null) { var sp = _viewport.Viewport.UnProject(pt); var junction = new JunctionL3d(); junction.Id = Yw.Untity.UniqueHelper.CreateFromFirst("junction", _nw.Junctions.Select(x => x.Id).ToList()); junction.Position = sp.Value.ToPointL3d(); AddVisual(junction); } else { var end = logicalNode.Position.ToPointL3d(); var valve = _visual as ValveL3d; if (valve != null) { valve.EndPosition = end; UpdateVisual(valve); } } _visual = null; _logicalMode = eLogicalEditMode.None; } break; default: { base.OnMouseUp(e); } break; } } //鼠标移动 protected override void OnMouseMove(MouseEventArgs e) { if (!Initialized) { return; } switch (_logicalMode) { case eLogicalEditMode.AddJunction: { } break; case eLogicalEditMode.AddPipe: { base.OnMouseMove(e); var pipe = _visual as PipeL3d; if (pipe != null) { var pt = e.GetPosition(_viewport); var sp = _viewport.Viewport.UnProject(pt); if (sp.HasValue) { pipe.EndPosition = sp.Value.ToPointL3d(); UpdateVisual(_visual); } } } break; case eLogicalEditMode.AddHorizPipe: { base.OnMouseMove(e); var pipe = _visual as PipeL3d; if (pipe != null) { var pt = e.GetPosition(_viewport); var sp = _viewport.Viewport.UnProject(pt); if (sp.HasValue) { pipe.EndPosition = new PointL3d(sp.Value.X, sp.Value.Y, pipe.StartPosition.Z); UpdateVisual(_visual); } } } break; case eLogicalEditMode.AddVertPipe: { base.OnMouseMove(e); var pipe = _visual as PipeL3d; if (pipe != null) { var pt = e.GetPosition(_viewport); var sp = _viewport.Viewport.UnProject(pt); if (sp.HasValue) { pipe.EndPosition = new PointL3d(pipe.StartPosition.X, pipe.StartPosition.Y, sp.Value.Z); UpdateVisual(_visual); } } } break; case eLogicalEditMode.AddPump: { base.OnMouseMove(e); var pump = _visual as PumpL3d; if (pump != null) { var pt = e.GetPosition(_viewport); var sp = _viewport.Viewport.UnProject(pt); if (sp.HasValue) { pump.EndPosition = sp.Value.ToPointL3d(); UpdateVisual(_visual); } } } break; case eLogicalEditMode.AddValve: { base.OnMouseMove(e); var valve = _visual as ValveL3d; if (valve != null) { var pt = e.GetPosition(_viewport); var sp = _viewport.Viewport.UnProject(pt); if (sp.HasValue) { valve.EndPosition = sp.Value.ToPointL3d(); UpdateVisual(_visual); } } } break; default: { base.OnMouseMove(e); } break; } } #endregion //添加 private void AddVisual(VisualL3d visual) { if (!Initialized) { return; } _nw.Append(visual, out string msg); _allVisualL3dDict.Add(visual.Id, visual); var logicalVisual = LogicalCreateHelper.Create(visual, _stateHelper, _materialHelper, _overrideColorHelper, _overrideOpacityHelper, _overrideVisibleHelper); if (logicalVisual != null) { _allVisualLogicalDict.Add(visual, logicalVisual); _viewport.Children.Add(logicalVisual); } } //更新 private void UpdateVisual(VisualL3d visual) { if (!Initialized) { return; } var logicalVisual = _allVisualLogicalDict[visual]; logicalVisual.UpdateVisual(); } #region 辅助方法 //吸附最近节点 private LogicalNode3D SnapNearestNode(Point pt) { if (!Initialized) { return default; } var logicalNode = _viewport.FindNearestVisual(pt) as LogicalNode3D; if (logicalNode == null) { var sp = _viewport.Viewport.UnProject(pt); if (sp.HasValue) { var snapDistance = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.SnapDistance; logicalNode = _viewport.Children.OfType() .OrderBy(x => (x.Position - sp.Value).LengthSquared) .FirstOrDefault(x => (x.Position - sp.Value).Length < snapDistance); } } return logicalNode; } //吸附最近节点 private LogicalNode3D SnapNearestNode(Point3D pt) { if (!Initialized) { return default; } var snapDistance = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.SnapDistance; var logicalNode = _viewport.Children.OfType() .OrderBy(x => (x.Position - pt).LengthSquared) .FirstOrDefault(x => (x.Position - pt).Length < snapDistance); return logicalNode; } #endregion } }