lixiaojun
2025-04-18 86fdd2266700b4f80a2d8b05b6a79d31802a7231
添加编辑功能
已修改15个文件
已添加6个文件
640 ■■■■■ 文件已修改
Yw.WpfUI.Hydro.L3d.Core/00-core/CameraL3dExtensions.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/00-core/Vector3DExtensions.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/01-network/00-core/NetworkL3d.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/01-network/00-core/NetworkL3d_Camera.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/01-network/99-model/01-camera/CameraL3d.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/02-settings/01-paras/01-node/00-core/Paras_HydroL3d_Logical_Node.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/02-settings/01-paras/02-link/00-core/Paras_HydroL3d_Logical_Link.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/01-node/01-junction/00-core/LogicalJunction3D.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/01-node/02-source/00-core/LogicalSource3D.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/02-link/01-pipe/LogicalPipe3D.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/02-link/02-pump/LogicalPump3D.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/02-link/03-valve/LogicalValve3D.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/02-state/eLogicalState.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/05-camera/LogicalCamera3D.cs 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/05-camera/LogicalCameraHelper.cs 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/08-manager/LogicalEditManager.cs 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/08-manager/LogicalManager.cs 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/03-logical/09-control/LogicalEditerL3d.xaml.cs 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/paras_hydrol3d_settings.json 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Test.Core/MainWindow.xaml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Test.Core/MainWindow.xaml.cs 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.WpfUI.Hydro.L3d.Core/00-core/CameraL3dExtensions.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
namespace Yw.WpfUI.Hydro
{
    /// <summary>
    /// ç›¸æœºæ‹“展
    /// </summary>
    internal static class CameraL3dExtensions
    {
        /// <summary>
        ///
        /// </summary>
        public static LogicalCamera3D ToLogicalCamera3D(this CameraL3d camera)
        {
            if (camera == null)
            {
                return default;
            }
            return new LogicalCamera3D()
            {
                NearPlaneDistance = camera.NearPlaneDistance,
                FarPlaneDistance = camera.FarPlaneDistance,
                Position = camera.Position.ToPoint3D(),
                UpDirection = camera.UpDirection.ToVector3D(),
                LookDirection = camera.LookDirection.ToVector3D(),
                FieldOfView = camera.FieldOfView,
                Width = camera.Width
            };
        }
    }
}
Yw.WpfUI.Hydro.L3d.Core/00-core/Vector3DExtensions.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
namespace Yw.WpfUI.Hydro
{
    /// <summary>
    ///
    /// </summary>
    internal static class Vector3DExtensions
    {
        /// <summary>
        ///
        /// </summary>
        public static PointL3d ToPointL3d(this Vector3D pt)
        {
            return new PointL3d(pt.X, pt.Y, pt.Z);
        }
    }
}
Yw.WpfUI.Hydro.L3d.Core/01-network/00-core/NetworkL3d.cs
@@ -22,6 +22,7 @@
        }
        private List<ParterL3d> _parters = new();
        /// <summary>
        /// å¯è§åˆ—表
        /// </summary>
Yw.WpfUI.Hydro.L3d.Core/01-network/00-core/NetworkL3d_Camera.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
namespace Yw.WpfUI.Hydro
{
    /// <summary>
    ///
    /// </summary>
    public partial class NetworkL3d
    {
        /// <summary>
        /// é»˜è®¤ç›¸æœº
        /// </summary>
        public CameraL3d DefaultCamera { get; set; }
    }
}
Yw.WpfUI.Hydro.L3d.Core/01-network/99-model/01-camera/CameraL3d.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
namespace Yw.WpfUI.Hydro
{
    /// <summary>
    /// ç›¸æœº
    /// </summary>
    public class CameraL3d
    {
        /// <summary>
        /// ç›¸æœºä½ç½®
        /// </summary>
        public PointL3d Position { get; set; }
        /// <summary>
        /// ç›¸æœºæ–¹å‘
        /// </summary>
        public PointL3d UpDirection { get; set; }
        /// <summary>
        /// è§‚察方向
        /// </summary>
        public PointL3d LookDirection { get; set; }
        /// <summary>
        /// è§†é‡Ž
        /// </summary>
        public double FieldOfView { get; set; }
        /// <summary>
        /// è¿‘平面距离
        /// </summary>
        public double NearPlaneDistance { get; set; }
        /// <summary>
        /// è¿œå¹³é¢è·ç¦»
        /// </summary>
        public double FarPlaneDistance { get; set; }
        /// <summary>
        /// æ­£å°„相机的宽度
        /// </summary>
        public double Width { get; set; }
    }
}
Yw.WpfUI.Hydro.L3d.Core/02-settings/01-paras/01-node/00-core/Paras_HydroL3d_Logical_Node.cs
@@ -21,6 +21,16 @@
        public Paras_HydroL3d_Point Selection { get; set; }
        /// <summary>
        /// å¢žåŠ 
        /// </summary>
        public Paras_HydroL3d_Point Adding { get; set; }
        /// <summary>
        /// ç¼–辑
        /// </summary>
        public Paras_HydroL3d_Point Editing { get; set; }
        /// <summary>
        /// å¸é™„距离
        /// </summary>
        public double SnapDistance { get; set; }
Yw.WpfUI.Hydro.L3d.Core/02-settings/01-paras/02-link/00-core/Paras_HydroL3d_Logical_Link.cs
@@ -20,7 +20,15 @@
        /// </summary>
        public Paras_HydroL3d_Line Selection { get; set; }
        /// <summary>
        /// å¢žåŠ 
        /// </summary>
        public Paras_HydroL3d_Line Adding { get; set; }
        /// <summary>
        /// ç¼–辑
        /// </summary>
        public Paras_HydroL3d_Line Editing { get; set; }
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/01-node/01-junction/00-core/LogicalJunction3D.cs
@@ -59,6 +59,14 @@
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Highlight.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Adding))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Adding.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Editing))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Editing.HtmlColor;
            }
            var material = _materialHelper.GetMaterial(htmlColor, opacity);
            this.Material = material;
        }
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/01-node/02-source/00-core/LogicalSource3D.cs
@@ -59,6 +59,14 @@
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Highlight.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Adding))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Adding.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Editing))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Editing.HtmlColor;
            }
            var material = _materialHelper.GetMaterial(htmlColor, opacity);
            this.Material = material;
        }
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/02-link/01-pipe/LogicalPipe3D.cs
@@ -59,6 +59,14 @@
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Link.Highlight.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Adding))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Adding.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Editing))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Editing.HtmlColor;
            }
            var material = _materialHelper.GetMaterial(htmlColor, opacity);
            this.Material = material;
        }
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/02-link/02-pump/LogicalPump3D.cs
@@ -61,6 +61,14 @@
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Link.Highlight.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Adding))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Adding.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Editing))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Editing.HtmlColor;
            }
            var material = _materialHelper.GetMaterial(htmlColor, opacity);
            this.Material = material;
        }
Yw.WpfUI.Hydro.L3d.Core/03-logical/01-visual/02-link/03-valve/LogicalValve3D.cs
@@ -56,6 +56,14 @@
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Link.Highlight.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Adding))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Adding.HtmlColor;
            }
            if (state.HasFlag(eLogicalState.Editing))
            {
                htmlColor = Yw.Settings.HydroL3dParasHelper.HydroL3d.Logical.Node.Editing.HtmlColor;
            }
            var material = _materialHelper.GetMaterial(htmlColor, opacity);
            this.Material = material;
        }
Yw.WpfUI.Hydro.L3d.Core/03-logical/02-state/eLogicalState.cs
@@ -44,12 +44,12 @@
        /// <summary>
        /// å¢žåŠ 
        /// </summary>
        Add = 0x64,
        Adding = 0x64,
        /// <summary>
        /// ç¼–辑
        /// </summary>
        Edit = 0x128,
        Editing = 0x128,
Yw.WpfUI.Hydro.L3d.Core/03-logical/05-camera/LogicalCamera3D.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@

namespace Yw.WpfUI.Hydro
{
    /// <summary>
    ///
    /// </summary>
    internal class LogicalCamera3D
    {
        /// <summary>
        ///
        /// </summary>
        public LogicalCamera3D() { }
        /// <summary>
        ///
        /// </summary>
        public LogicalCamera3D(CameraSetting rhs)
        {
            this.FarPlaneDistance = rhs.FarPlaneDistance;
            this.FieldOfView = rhs.FieldOfView;
            this.LookDirection = rhs.LookDirection;
            this.NearPlaneDistance = rhs.NearPlaneDistance;
            this.Position = rhs.Position;
            this.UpDirection = rhs.UpDirection;
            this.Width = rhs.Width;
        }
        /// <summary>
        /// è¿œå¹³é¢è·ç¦»
        /// </summary>
        public double FarPlaneDistance { get; set; }
        /// <summary>
        /// è§†é‡Ž
        /// </summary>
        public double FieldOfView { get; set; }
        /// <summary>
        /// è§‚察方向
        /// </summary>
        public Vector3D LookDirection { get; set; }
        /// <summary>
        /// è¿‘平面距离
        /// </summary>
        public double NearPlaneDistance { get; set; }
        /// <summary>
        /// ç›¸æœºä½ç½®
        /// </summary>
        public Point3D Position { get; set; }
        /// <summary>
        /// ç›¸æœºæ–¹å‘
        /// </summary>
        public Vector3D UpDirection { get; set; }
        /// <summary>
        /// æ­£äº¤ç›¸æœºçš„宽度
        /// </summary>
        public double Width { get; set; }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public CameraL3d ToCameraL3d()
        {
            return new CameraL3d()
            {
                Width = this.Width,
                NearPlaneDistance = this.NearPlaneDistance,
                FarPlaneDistance = this.FarPlaneDistance,
                FieldOfView = this.FieldOfView,
                Position = this.Position.ToPointL3d(),
                LookDirection = this.LookDirection.ToPointL3d(),
                UpDirection = this.UpDirection.ToPointL3d()
            };
        }
    }
}
Yw.WpfUI.Hydro.L3d.Core/03-logical/05-camera/LogicalCameraHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,82 @@
namespace Yw.WpfUI.Hydro
{
    /// <summary>
    /// æŠ½è±¡ç›¸æœºè¾…助类
    /// </summary>
    internal class LogicalCameraHelper
    {
        /// <summary>
        ///
        /// </summary>
        public LogicalCameraHelper(HelixViewport3D viewport)
        {
            _viewport = viewport;
        }
        /// <summary>
        /// ä¿å­˜é»˜è®¤ç›¸æœºäº‹ä»¶
        /// </summary>
        public event Action<LogicalCamera3D> SaveDefaultCameraEvent;
        private readonly HelixViewport3D _viewport = null;//三维组件
        private LogicalCamera3D _defaultCamera = null;//默认相机设置
        /// <summary>
        /// è®¾ç½®é»˜è®¤ç›¸æœº
        /// </summary>
        public void SetDefault(CameraL3d camera)
        {
            if (camera == null)
            {
                return;
            }
            _defaultCamera = camera.ToLogicalCamera3D();
        }
        /// <summary>
        /// ä¿å­˜é»˜è®¤ç›¸æœº
        /// </summary>
        public void SaveDefault()
        {
            var cameraSetting = new CameraSetting(_viewport.Camera);
            var logicalCamera = new LogicalCamera3D(cameraSetting);
            _defaultCamera = logicalCamera;
            this.SaveDefaultCameraEvent?.Invoke(logicalCamera);
        }
        /// <summary>
        /// èŽ·å–é»˜è®¤ç›¸æœº
        /// </summary>
        /// <returns></returns>
        public LogicalCamera3D GetDefault()
        {
            return _defaultCamera;
        }
        /// <summary>
        /// åº”用默认相机
        /// </summary>
        public void ApplyDefault()
        {
            if (_defaultCamera == null)
            {
                return;
            }
            var camera = _viewport.Camera;
            camera.NearPlaneDistance = _defaultCamera.NearPlaneDistance;
            camera.FarPlaneDistance = _defaultCamera.FarPlaneDistance;
            camera.Position = _defaultCamera.Position;
            camera.LookDirection = _defaultCamera.LookDirection;
            camera.UpDirection = _defaultCamera.UpDirection;
            if (camera is PerspectiveCamera perspectiveCamera)
            {
                perspectiveCamera.FieldOfView = _defaultCamera.FieldOfView;
            }
            else if (camera is OrthographicCamera orghographicCamera)
            {
                orghographicCamera.Width = _defaultCamera.Width;
            }
        }
    }
}
Yw.WpfUI.Hydro.L3d.Core/03-logical/08-manager/LogicalEditManager.cs
@@ -15,7 +15,7 @@
        private eLogicalEditMode _logicalMode = eLogicalEditMode.None;//编辑模式
        private LogicalVisual3D _addLogicalVisual;//添加抽象对象
        private LogicalVisual3D _editLogicalVisual;//编辑抽象对象
        private LogicalNode3D _editLogicalNode;//编辑抽象节点
        #region æ·»åŠ æ–¹æ³•
@@ -96,6 +96,14 @@
            _logicalMode = eLogicalEditMode.Edit;
        }
        /// <summary>
        /// ç»“束编辑
        /// </summary>
        public void EndEdit()
        {
            _logicalMode = eLogicalEditMode.None;
        }
        #endregion
        #region é‡å†™äº‹ä»¶
@@ -121,6 +129,7 @@
                            junction.Catalog = CatalogL3d.Junction;
                            junction.Name = _nw.CreateName(CatalogL3d.Junction);
                            junction.Position = sp.Value.ToPointL3d();
                            _stateHelper.LoadState(junction, eLogicalState.Adding);
                            var logicalJunction = CreateLogicalVisual(junction);
                            logicalJunction.UpdateVisual();
                            AddLogicalVisual(logicalJunction);
@@ -139,6 +148,7 @@
                            reservoir.Catalog = CatalogL3d.Reservoir;
                            reservoir.Name = _nw.CreateName(CatalogL3d.Reservoir);
                            reservoir.Position = sp.Value.ToPointL3d();
                            _stateHelper.LoadState(reservoir, eLogicalState.Adding);
                            var logicalReservoir = CreateLogicalVisual(reservoir);
                            logicalReservoir.UpdateVisual();
                            AddLogicalVisual(logicalReservoir);
@@ -157,6 +167,7 @@
                            tank.Catalog = CatalogL3d.Tank;
                            tank.Name = _nw.CreateName(CatalogL3d.Tank);
                            tank.Position = sp.Value.ToPointL3d();
                            _stateHelper.LoadState(tank, eLogicalState.Adding);
                            var logicalTank = CreateLogicalVisual(tank);
                            logicalTank.UpdateVisual();
                            AddLogicalVisual(logicalTank);
@@ -175,6 +186,7 @@
                            pipe.Catalog = CatalogL3d.Pipe;
                            pipe.Name = _nw.CreateName(CatalogL3d.Pipe);
                            pipe.StartNode = logicalNode.Vmo;
                            _stateHelper.LoadState(pipe, eLogicalState.Adding);
                            var logicalPipe = CreateLogicalVisual(pipe) as LogicalPipe3D;
                            logicalPipe.EndPosition = logicalNode.Position;
                            logicalPipe.UpdateVisual();
@@ -194,6 +206,7 @@
                            pipe.Catalog = CatalogL3d.Pipe;
                            pipe.Name = _nw.CreateName(CatalogL3d.Pipe);
                            pipe.StartNode = logicalNode.Vmo;
                            _stateHelper.LoadState(pipe, eLogicalState.Adding);
                            var logicalPipe = CreateLogicalVisual(pipe) as LogicalPipe3D;
                            logicalPipe.EndPosition = logicalNode.Position;
                            logicalPipe.UpdateVisual();
@@ -213,6 +226,7 @@
                            pipe.Catalog = CatalogL3d.Pipe;
                            pipe.Name = _nw.CreateName(CatalogL3d.Pipe);
                            pipe.StartNode = logicalNode.Vmo;
                            _stateHelper.LoadState(pipe, eLogicalState.Adding);
                            var logicalPipe = CreateLogicalVisual(pipe) as LogicalPipe3D;
                            logicalPipe.EndPosition = logicalNode.Position;
                            logicalPipe.UpdateVisual();
@@ -232,6 +246,7 @@
                            pump.Catalog = CatalogL3d.Pump;
                            pump.Name = _nw.CreateName(CatalogL3d.Pump);
                            pump.StartNode = logicalNode.Vmo;
                            _stateHelper.LoadState(pump, eLogicalState.Adding);
                            var logicalPump = CreateLogicalVisual(pump) as LogicalPump3D;
                            logicalPump.EndPosition = logicalNode.Position;
                            logicalPump.UpdateVisual();
@@ -251,11 +266,24 @@
                            valve.Catalog = CatalogL3d.Valve;
                            valve.Name = _nw.CreateName(CatalogL3d.Valve);
                            valve.StartNode = logicalNode.Vmo;
                            _stateHelper.LoadState(valve, eLogicalState.Adding);
                            var logicalValve = CreateLogicalVisual(valve) as LogicalValve3D;
                            logicalValve.EndPosition = logicalNode.Position;
                            logicalValve.UpdateVisual();
                            AddLogicalVisual(logicalValve);
                            _addLogicalVisual = logicalValve;
                        }
                    }
                    break;
                case eLogicalEditMode.Edit:
                    {
                        var pt = e.GetPosition(_viewport);
                        var logicalNode = SnapNearestNode(pt);
                        if (logicalNode != null)
                        {
                            var node = logicalNode.Vmo;
                            _stateHelper.LoadState(logicalNode.Vmo, eLogicalState.Editing);
                            _editLogicalNode = logicalNode;
                        }
                    }
                    break;
@@ -402,6 +430,24 @@
                        }
                    }
                    break;
                case eLogicalEditMode.Edit:
                    {
                        base.OnMouseMove(e);
                        if (_editLogicalNode != null)
                        {
                            var pt = e.GetPosition(_viewport);
                            var sp = _viewport.Viewport.UnProject(pt);
                            if (sp.HasValue)
                            {
                                var node = _editLogicalNode.Vmo;
                                node.Position = sp.Value.ToPointL3d();
                                _editLogicalNode.UpdateVisual();
                                var links = _nw.Links.Where(x => x.StartNode == node || x.EndNode == node).ToList();
                                links?.ForEach(x => _allVisualLogicalDict[x].UpdateVisual());
                            }
                        }
                    }
                    break;
                default:
                    {
                        base.OnMouseMove(e);
@@ -424,6 +470,7 @@
                        var logicalJunction = _addLogicalVisual as LogicalJunction3D;
                        if (logicalJunction != null)
                        {
                            _stateHelper.UnloadState(logicalJunction.Vmo, eLogicalState.Adding);
                            if (!logicalJunction.Verify())
                            {
                                RemoveLogicalVisual(logicalJunction);
@@ -438,6 +485,7 @@
                        var logicalReservoir = _addLogicalVisual as LogicalReservoir3D;
                        if (logicalReservoir != null)
                        {
                            _stateHelper.UnloadState(logicalReservoir.Vmo, eLogicalState.Adding);
                            if (!logicalReservoir.Verify())
                            {
                                RemoveLogicalVisual(logicalReservoir);
@@ -452,6 +500,7 @@
                        var logicalTank = _addLogicalVisual as LogicalTank3D;
                        if (logicalTank != null)
                        {
                            _stateHelper.UnloadState(logicalTank.Vmo, eLogicalState.Adding);
                            if (!logicalTank.Verify())
                            {
                                RemoveLogicalVisual(logicalTank);
@@ -466,6 +515,7 @@
                        var logicalPipe = _addLogicalVisual as LogicalPipe3D;
                        if (logicalPipe != null)
                        {
                            _stateHelper.UnloadState(logicalPipe.Vmo, eLogicalState.Adding);
                            var pt = e.GetPosition(_viewport);
                            var logicalNode = SnapNearestNode(pt);
                            if (logicalNode == null)
@@ -499,6 +549,7 @@
                        var logicalPipe = _addLogicalVisual as LogicalPipe3D;
                        if (logicalPipe != null)
                        {
                            _stateHelper.UnloadState(logicalPipe.Vmo, eLogicalState.Adding);
                            var end = logicalPipe.EndPosition;
                            var logicalNode = SnapNearestNode(end);
                            if (logicalNode == null)
@@ -531,6 +582,7 @@
                        var logicalPipe = _addLogicalVisual as LogicalPipe3D;
                        if (logicalPipe != null)
                        {
                            _stateHelper.UnloadState(logicalPipe.Vmo, eLogicalState.Adding);
                            var end = logicalPipe.EndPosition;
                            var logicalNode = SnapNearestNode(end);
                            if (logicalNode == null)
@@ -563,6 +615,7 @@
                        var logicalPump = _addLogicalVisual as LogicalPump3D;
                        if (logicalPump != null)
                        {
                            _stateHelper.UnloadState(logicalPump.Vmo, eLogicalState.Adding);
                            var pt = e.GetPosition(_viewport);
                            var logicalNode = SnapNearestNode(pt);
                            if (logicalNode == null)
@@ -596,6 +649,7 @@
                        var logicalValve = _addLogicalVisual as LogicalValve3D;
                        if (logicalValve != null)
                        {
                            _stateHelper.UnloadState(logicalValve.Vmo, eLogicalState.Adding);
                            var pt = e.GetPosition(_viewport);
                            var logicalNode = SnapNearestNode(pt);
                            if (logicalNode == null)
@@ -624,6 +678,15 @@
                        }
                    }
                    break;
                case eLogicalEditMode.Edit:
                    {
                        if (_editLogicalNode != null)
                        {
                            _stateHelper.UnloadState(_editLogicalNode.Vmo, eLogicalState.Editing);
                        }
                        _editLogicalNode = null;
                    }
                    break;
                default:
                    {
                        base.OnMouseUp(e);
Yw.WpfUI.Hydro.L3d.Core/03-logical/08-manager/LogicalManager.cs
@@ -1,4 +1,6 @@
namespace Yw.WpfUI.Hydro
using System.Windows.Controls;
namespace Yw.WpfUI.Hydro
{
    /// <summary>
    /// æŠ½è±¡ç®¡ç†å™¨
@@ -19,6 +21,7 @@
            _selectionHelper = new LogicalSelectionHelper(_viewport);
            _zoomHelper = new LogicalZoomHelper(_viewport);
            _billboardTextHelper = new LogicalBillboardLeadLabelHelper(_viewport);
            _cameraHelper = new LogicalCameraHelper(_viewport);
        }
        #region äº‹ä»¶é›†åˆ
@@ -44,6 +47,7 @@
        protected readonly LogicalSelectionHelper _selectionHelper = null;//选择辅助类
        protected readonly LogicalZoomHelper _zoomHelper = null;//缩放辅助类
        protected readonly LogicalBillboardLeadLabelHelper _billboardTextHelper = null;//公告版文字辅助类
        protected readonly LogicalCameraHelper _cameraHelper = null;//相机辅助类
        #endregion
@@ -215,6 +219,11 @@
            _viewport.Children.Add(new SunLight());
            _allVisualLogicalDict?.Values.ToList().ForEach(x => _viewport.Children.Add(x));
            _viewport.ZoomExtents();
            if (_nw.DefaultCamera != null)
            {
                _cameraHelper.SetDefault(_nw.DefaultCamera);
                _cameraHelper.ApplyDefault();
            }
        }
@@ -366,6 +375,10 @@
                _selectionHelper.StateChangedEvent += SelectionHelper_StateChangedEvent;
                _selectionHelper.SelectionChangedEvent += SelectionHelper_SelectionChangedEvent;
            }
            if (_cameraHelper != null)
            {
                _cameraHelper.SaveDefaultCameraEvent += CameraHelper_SaveDefaultCameraEvent;
            }
        }
        //高亮状态改变事件
@@ -409,6 +422,13 @@
        {
            var visuals = obj?.Select(x => x.Vmo).ToList();
            this.SelectionChangedEvent?.Invoke(visuals);
        }
        //默认相机保存事件
        private void CameraHelper_SaveDefaultCameraEvent(LogicalCamera3D logicalCamera)
        {
            var camera = logicalCamera.ToCameraL3d();
            _nw.DefaultCamera = camera;
        }
@@ -460,7 +480,6 @@
            _viewport.FitView(lookDirection, upDirection);
        }
        /// <summary>
        /// è®¾ç½®å³è§†å›¾
        /// </summary>
@@ -500,6 +519,66 @@
            }
            var lookDirection = new Vector3D(0, -1, 0);   // å‘前看
            var upDirection = new Vector3D(0, 0, 1);// Z轴朝上
            _viewport.FitView(lookDirection, upDirection);
        }
        /// <summary>
        /// è¥¿å—视角
        /// ä»Žç‰©ä½“的左前下方观察
        /// </summary>
        public virtual void SetSouthWestView()
        {
            if (!Initialized)
            {
                return;
            }
            var lookDirection = new Vector3D(1, 1, -1);
            var upDirection = new Vector3D(0, 0, 1);
            _viewport.FitView(lookDirection, upDirection);
        }
        /// <summary>
        /// ä¸œå—视角
        /// ä»Žç‰©ä½“的右前下方观察
        /// </summary>
        public virtual void SetSouthEastView()
        {
            if (!Initialized)
            {
                return;
            }
            var lookDirection = new Vector3D(-1, 1, -1);
            var upDirection = new Vector3D(0, 0, 1);
            _viewport.FitView(lookDirection, upDirection);
        }
        /// <summary>
        /// ä¸œåŒ—视角
        /// ä»Žç‰©ä½“的右后上方观察
        /// </summary>
        public virtual void SetNorthEastView()
        {
            if (!Initialized)
            {
                return;
            }
            var lookDirection = new Vector3D(-1, -1, -1);
            var upDirection = new Vector3D(0, 0, 1);
            _viewport.FitView(lookDirection, upDirection);
        }
        /// <summary>
        /// è¥¿åŒ—视角
        /// ä»Žç‰©ä½“的左后上方观察
        /// </summary>
        public virtual void SetNorthWestView()
        {
            if (!Initialized)
            {
                return;
            }
            var lookDirection = new Vector3D(1, -1, -1);
            var upDirection = new Vector3D(0, 0, 1);
            _viewport.FitView(lookDirection, upDirection);
        }
@@ -684,7 +763,33 @@
        #endregion
        #region ç›¸æœº
        /// <summary>
        /// ä¿å­˜é»˜è®¤ç›¸æœº
        /// </summary>
        public void SaveDefaultCamera()
        {
            if (!Initialized)
            {
                return;
            }
            _cameraHelper.SaveDefault();
        }
        /// <summary>
        /// åº”用默认相机
        /// </summary>
        public void ApplyDefaultCamera()
        {
            if (!Initialized)
            {
                return;
            }
            _cameraHelper.ApplyDefault();
        }
        #endregion
Yw.WpfUI.Hydro.L3d.Core/03-logical/09-control/LogicalEditerL3d.xaml.cs
@@ -124,6 +124,26 @@
            _manager.SetBackView();
        }
        public void SetNorthWestView()
        {
            _manager.SetNorthWestView();
        }
        public void SetNorthEastView()
        {
            _manager.SetNorthEastView();
        }
        public void SetSouthWestView()
        {
            _manager.SetSouthWestView();
        }
        public void SetSouthEastView()
        {
            _manager.SetSouthEastView();
        }
        #endregion
        #region å…¬å‘Šæ¿æ–‡æœ¬
@@ -201,5 +221,32 @@
        #endregion
        #region ç›¸æœº
        public void SaveDefaultCamera()
        {
            _manager.SaveDefaultCamera();
        }
        public void ApplyDefaultCamera()
        {
            _manager.ApplyDefaultCamera();
        }
        #endregion
        #region ç¼–辑
        public void StartEdit()
        {
            _manager.StartEdit();
        }
        public void EndEdit()
        {
            _manager.EndEdit();
        }
        #endregion
    }
}
Yw.WpfUI.Hydro.L3d.Core/paras_hydrol3d_settings.json
@@ -14,8 +14,16 @@
                    "Radius": 0.5
                },
                "Selection": {
                    "HtmlColor": "#FF1493",
                    "HtmlColor": "#DAA520",
                    "Radius": 0.4
                },
                "Adding": {
                    "HtmlColor": "#808080",
                    "Radius": 0.3
                },
                "Editing": {
                    "HtmlColor": "#00BFFF",
                    "Radius": 0.3
                },
                "SnapDistance": 0.2
            },
@@ -29,8 +37,16 @@
                    "Diameter": 0.8
                },
                "Selection": {
                    "HtmlColor": "#FF1493",
                    "HtmlColor": "#DAA520",
                    "Diameter": 0.6
                },
                "Adding": {
                    "HtmlColor": "#808080",
                    "Radius": 0.3
                },
                "Editing": {
                    "HtmlColor": "#00BFFF",
                    "Radius": 0.3
                }
            }
        }
Yw.WpfUI.Test.Core/MainWindow.xaml
@@ -91,6 +91,32 @@
                    </ContextMenu>
                </Button.ContextMenu>
            </Button>
            <Button Content="等轴视角">
                <Button.ContextMenu>
                    <ContextMenu>
                        <MenuItem Click="SouthWestMenuItem_Click" Header="西南视角" />
                        <MenuItem Click="SouthEastMenuItem_Click" Header="东南视角" />
                        <MenuItem Click="NonthWestMenuItem_Click" Header="西北视角" />
                        <MenuItem Click="NonthEastMenuItem_Click" Header="东北视角" />
                    </ContextMenu>
                </Button.ContextMenu>
            </Button>
            <Button Content="默认相机">
                <Button.ContextMenu>
                    <ContextMenu>
                        <MenuItem Click="SaveDefaultCameraMenuItem_Click" Header="保存" />
                        <MenuItem Click="ApplyDefaultCameraMenuItem_Click" Header="应用" />
                    </ContextMenu>
                </Button.ContextMenu>
            </Button>
            <Button Content="编辑">
                <Button.ContextMenu>
                    <ContextMenu>
                        <MenuItem Click="StartEditMenuItem_Click" Header="开始" />
                        <MenuItem Click="EndEditCameraMenuItem_Click" Header="结束" />
                    </ContextMenu>
                </Button.ContextMenu>
            </Button>
            <Separator />
            <Button Click="BillboardText_Click" Content="文本" />
            <CheckBox
Yw.WpfUI.Test.Core/MainWindow.xaml.cs
@@ -198,6 +198,46 @@
        {
            this.editer.BackgroudVisible = false;
        }
        private void SouthWestMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.editer.SetSouthWestView();
        }
        private void SouthEastMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.editer.SetSouthEastView();
        }
        private void NonthWestMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.editer.SetNorthWestView();
        }
        private void NonthEastMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.editer.SetNorthEastView();
        }
        private void SaveDefaultCameraMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.editer.SaveDefaultCamera();
        }
        private void ApplyDefaultCameraMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.editer.ApplyDefaultCamera();
        }
        private void StartEditMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.editer.StartEdit();
        }
        private void EndEditCameraMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.editer.EndEdit();
        }
    }