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