lixiaojun
2024-09-25 21c97aab9153758bebfc9b3944859b0eec271c76
WinFrmUI/Yw.WinFrmUI.Hydro.L3d.Core/02-panel/NetworkPanel.cs
@@ -1,16 +1,6 @@
using DevExpress.XtraBars.Docking.Paint;
using DevExpress.XtraEditors;
using SharpGL;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media;
using DevExpress.CodeParser;
using DevExpress.XtraCharts.Native;
using Yw.Untity;
namespace Yw.WinFrmUI.HydroL3d
{
@@ -19,11 +9,19 @@
        public NetworkPanel()
        {
            InitializeComponent();
            this.openGLControl1.MouseWheel += openGLControl1_MouseWheel;
            this.propertyGridControl1.CellValueChanged += PropertyGridControl1_CellValueChanged;
        }
        protected Network _network = null;//管网
        protected BoundingBox3d _bounndingBox = null;//包围盒
        protected Point3d _center = null;//中心
        private Network _network = null;//管网
        private NetworkParas _paras = null;//参数
        private float _zoom = 1f;//缩放
        private float _rotationX = 0.0f;//x旋转角度
        private float _rotationY = 0.0f;//y旋转角度
        private float _viewPortX = 0f;//
        private float _viewPortY = 0f;//
        /// <summary>
        /// 是否初始化
@@ -37,108 +35,50 @@
        public virtual void Initial(Network network)
        {
            _network = network;
            _bounndingBox = _network.GetBoundingBox();
            _center = _bounndingBox.GetCenter();
            _paras = _network.GetParas();
            InitialParas();
            this.propertyGridControl1.SelectedObject = _paras;
        }
        private void openGLControl1_OpenGLDraw(object sender, RenderEventArgs args)
        //初始化参数
        private void InitialParas()
        {
            if (_network == null)
            {
                return;
            }
            SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
            //清除深度缓存
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
            //重置当前指定的矩阵为单位矩阵,将当前的用户坐标系的原点移到了屏幕中心
            gl.LoadIdentity();
            gl.Translate(-_center.X, -_center.Y, -_bounndingBox.Max.Z);
            foreach (var pipe in _network.Pipes)
            {
                var startPosition = pipe.StartPosition;
                var endPosition = pipe.EndPosition;
                gl.Begin(OpenGL.GL_LINES);
                gl.Color(1.0f, 1.0f, 1.0f);
                gl.Vertex(startPosition.X, startPosition.Y, startPosition.Z);//左顶点
                gl.Vertex(endPosition.X, endPosition.Y, endPosition.Z);//右顶点
                gl.End();
            }
            //坐标轴变换位置到(0.0f, 0.0f, -5.0f),这样我们的坐标轴就相当于往屏幕内走5个单位
            //gl.Translate(0.0f, 0.0f, -5.0f);
            //rotation_X += 1f;
            //gl.Rotate(rotation_X, 1.0f, 0.0f, 0.0f);//rotationX:角度
            //rotation_Y += 1f;
            //gl.Rotate(rotation_Y, 0.0f, 1.0f, 0.0f);//rotationY:角度
            //rotation_Z += 1f;
            //gl.Rotate(rotation_Z, 0.0f, 0.0f, 1.0f);//rotationZ:角度
            //#region 点到线
            //gl.Begin(OpenGL.GL_LINES);
            //gl.Color(1.0f, 1.0f, 1.0f);
            //gl.Vertex(-2.0f, 0.0f, 0.0f);//左顶点
            //gl.Vertex(2.0f, 2.0f, 0.0f);//右顶点
            //gl.End();
            //#endregion
            //#region 线成面(三角形)
            //gl.Begin(OpenGL.GL_TRIANGLES);//第一个面
            //gl.Color(1.0f, 0.0f, 0.0f);
            //gl.Vertex(0.0f, 1f, 0.0f);//顶点
            //gl.Color(0.0f, 1.0f, 0.0f);
            //gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点
            //gl.Color(0.0f, 0.0f, 1.0f);
            //gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
            //gl.End();
            //#endregion
            //#region 面组合成体
            //gl.Begin(OpenGL.GL_TRIANGLES);//第二个面
            //gl.Color(1.0f, 1.0f, 1.0f);
            //gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
            //gl.Color(0.0f, 1.0f, 0.0f);
            //gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点
            //gl.Color(0.0f, 0.0f, 1.0f);
            //gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
            //gl.End();
            //gl.Begin(OpenGL.GL_TRIANGLES);//第三个面
            //gl.Color(1.0f, 1.0f, 1.0f);
            //gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
            //gl.Color(0.0f, 1.0f, 0.0f);
            //gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点
            //gl.Color(1.0f, 0.0f, 0.0f);
            //gl.Vertex(0.0f, 1f, 0.0f);//顶点
            //gl.End();
            //gl.Begin(OpenGL.GL_TRIANGLES);//第四个面
            //gl.Color(1.0f, 1.0f, 1.0f);
            //gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
            //gl.Color(0.0f, 0.0f, 1.0f);
            //gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
            //gl.Color(1.0f, 0.0f, 0.0f);
            //gl.Vertex(0.0f, 1f, 0.0f);//顶点
            //gl.End();
            //#endregion
            gl.Flush();   //强制刷新
            _zoom = _paras.Scale.X;
            _rotationX = _paras.Rotation.X;
            _rotationY = _paras.Rotation.Y;
            _viewPortX = 0f;
            _viewPortY = 0f;
        }
        private void PropertyGridControl1_CellValueChanged(object sender, DevExpress.XtraVerticalGrid.Events.CellValueChangedEventArgs e)
        {
            InitialParas();
            this.openGLControl1.Refresh();
        }
        //OpenGL 初始化
        private void openGLControl1_OpenGLInitialized(object sender, EventArgs e)
        {
            OpenGL gl = openGLControl1.OpenGL;
            gl.ClearColor(0, 0, 0, 0);
            gl.ClearColor(214 / 255f, 224 / 255f, 235 / 255f, 0);
        }
        private void openGLControl1_Resize(object sender, EventArgs e)
        //OpenGL 绘制
        private void openGLControl1_OpenGLDraw(object sender, RenderEventArgs args)
        {
            if (_network == null)
            if (!Initialized)
            {
                return;
            }
            OpenGL gl = openGLControl1.OpenGL;
            //启用深度测试
            gl.Enable(OpenGL.GL_DEPTH_TEST);
            //清除深度缓存
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
            // 设置视口
            gl.Viewport((int)_viewPortX, (int)_viewPortY, this.openGLControl1.Width, this.openGLControl1.Height);
            // 设置当前矩阵模式,对投影矩阵应用随后的矩阵操作
            gl.MatrixMode(OpenGL.GL_PROJECTION);
@@ -147,16 +87,266 @@
            gl.LoadIdentity();
            // 创建透视投影变换
            //gl.Perspective(30.0f, (double)Width / (double)Height, 5, 100);
            gl.Perspective(150, (double)Width / (double)Height, 5, _bounndingBox.Max.Z);
            // 视点变换
            //gl.LookAt(0, 5, 0, 0, 0, 0, 0, 1, 0);
            gl.LookAt(_center.X, _center.Y, 0, _center.X, _center.Y, _center.Z, 0, 1, 0);
            gl.Perspective(_paras.Perspective.Fovy, _paras.Perspective.Aspect, _paras.Perspective.Near, _paras.Perspective.Far);
            // 设置当前矩阵为模型视图矩阵
            gl.MatrixMode(OpenGL.GL_MODELVIEW);
            //重置当前指定的矩阵为单位矩阵,将当前的用户坐标系的原点移到了屏幕中心
            gl.LoadIdentity();
            //平移
            gl.Translate(_paras.Translation.X, _paras.Translation.Y, _paras.Translation.Z);
            //将z轴向上
            //gl.Rotate(90f, 1f, 0f, 0f);
            //旋转
            gl.Rotate(_rotationX, 1, 0, 0);
            gl.Rotate(_rotationY, 0, 1, 0);
            //缩放
            gl.Scale(_zoom, _zoom, _zoom);
            _network.Draw(gl);
            gl.LookAt(_paras.LookAt.Eye.X, _paras.LookAt.Eye.Y, _paras.LookAt.Eye.Z,
                _paras.LookAt.Center.X, _paras.LookAt.Center.Y, _paras.LookAt.Center.Z,
                _paras.LookAt.Up.X, _paras.LookAt.Up.Y, _paras.LookAt.Up.Z);
            gl.Flush();   //强制刷新
        }
        //Resize
        private void openGLControl1_Resized(object sender, EventArgs e)
        {
            if (!Initialized)
            {
                return;
            }
            _paras.Perspective.Aspect = (float)this.openGLControl1.Width / (float)this.openGLControl1.Height;
            _viewPortX = 0f;
            _viewPortY = 0f;
        }
        #region 鼠标左键按下旋转
        /// <summary>
        /// 当鼠标左键按下时允许旋转
        /// </summary>
        [Browsable(true)]
        [Description("当鼠标左键按下时允许旋转")]
        [DefaultValue(true)]
        public bool AllowRotateWhenMouseLeftDown
        {
            get => _allowRotateWhenMouseLeftDown;
            set => _allowRotateWhenMouseLeftDown = value;
        }
        private bool _allowRotateWhenMouseLeftDown = true;
        protected bool _hasMouseLeftDown = false;//鼠标左键是否按下
        protected Point _mouseLeftDownRotatePoint;//鼠标左键按下旋转点
        /// <summary>
        /// 判断鼠标左键是否按下
        /// </summary>
        protected virtual bool HasMouseLeftDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _hasMouseLeftDown = true;
                _mouseLeftDownRotatePoint = e.Location;
                return true;
            }
            return false;
        }
        /// <summary>
        /// 鼠标左键按下旋转
        /// </summary>
        protected virtual bool MouseLeftDownRotate(MouseEventArgs e)
        {
            if (_hasMouseLeftDown)
            {
                if (this.AllowRotateWhenMouseLeftDown)
                {
                    if (this.Initialized)
                    {
                        int deltaX = e.X - _mouseLeftDownRotatePoint.X;
                        int deltaY = e.Y - _mouseLeftDownRotatePoint.Y;
                        _rotationX += deltaY * 0.05f;
                        _rotationY += deltaX * 0.05f;
                        _mouseLeftDownRotatePoint = e.Location;
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 判断鼠标左键是否弹起
        /// </summary>
        protected virtual bool HasMouseLeftUp(MouseEventArgs e)
        {
            if (_hasMouseLeftDown)
            {
                _hasMouseLeftDown = false;
                return true;
            }
            return false;
        }
        #endregion
        #region 鼠标右键按下拖动
        /// <summary>
        /// 当鼠标右键按下时允许拖动
        /// </summary>
        [Browsable(true)]
        [Description("当鼠标右键按下时允许拖动")]
        [DefaultValue(true)]
        public bool AllowMoveWhenMouseRightDown
        {
            get => _allowMoveWhenMouseRightDown;
            set => _allowMoveWhenMouseRightDown = value;
        }
        private bool _allowMoveWhenMouseRightDown = true;
        protected bool _hasMouseRightDown = false;//鼠标右键是否按下
        protected Point _mouseRightDownMovePoint;//鼠标右键按下移动点
        /// <summary>
        /// 判断鼠标右键是否按下
        /// </summary>
        protected virtual bool HasMouseRightDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                _hasMouseRightDown = true;
                _mouseRightDownMovePoint = e.Location;
                return true;
            }
            return false;
        }
        /// <summary>
        /// 鼠标右键按下移动
        /// </summary>
        protected virtual bool MouseRightDownMove(MouseEventArgs e)
        {
            if (_hasMouseRightDown)
            {
                if (this.AllowMoveWhenMouseRightDown)
                {
                    if (this.Initialized)
                    {
                        int deltaX = e.X - _mouseRightDownMovePoint.X;
                        int deltaY = e.Y - _mouseRightDownMovePoint.Y;
                        _viewPortX += deltaX;
                        _viewPortY -= deltaY;
                        _mouseRightDownMovePoint = e.Location;
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 判断鼠标左键是否弹起
        /// </summary>
        protected virtual bool HasMouseRightUp(MouseEventArgs e)
        {
            if (_hasMouseRightDown)
            {
                _hasMouseRightDown = false;
                return true;
            }
            return false;
        }
        #endregion
        #region 鼠标事件
        private void openGLControl1_MouseDown(object sender, MouseEventArgs e)
        {
            HasMouseLeftDown(e);
            HasMouseRightDown(e);
        }
        private void openGLControl1_MouseMove(object sender, MouseEventArgs e)
        {
            var list = this.openGLControl1.OpenGL.UnProject(e.X, e.Y, 0);
            this.labelControl1.Text = DoubleListHelper.ToString(list);
            var hasMouseLeftDownRotate = MouseLeftDownRotate(e);
            var hasMouseRightDownMove = MouseRightDownMove(e);
            if (hasMouseLeftDownRotate || hasMouseRightDownMove)
            {
                this.openGLControl1.Invalidate();
            }
        }
        private void openGLControl1_MouseUp(object sender, MouseEventArgs e)
        {
            var hasMouseLeftUp = HasMouseLeftUp(e);
            var hasMouseRightUp = HasMouseRightUp(e);
            if (hasMouseLeftUp || hasMouseRightUp)
            {
                this.openGLControl1.Invalidate();
            }
        }
        private void openGLControl1_MouseHover(object sender, EventArgs e)
        {
            if (!Initialized)
            {
                return;
            }
            var pt = this.openGLControl1.PointToClient(MousePosition);
            var list = this.openGLControl1.OpenGL.UnProject(pt.X, pt.Y, 0);
            var wpt = new Point3d(list[0], list[1], list[2]);
            _network.Hover(wpt);
        }
        private void openGLControl1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (!Initialized)
            {
                return;
            }
            if (e.Button == MouseButtons.Left)
            {
                InitialParas();
                this.openGLControl1.Invalidate();
            }
        }
        private void openGLControl1_MouseClick(object sender, MouseEventArgs e)
        {
        }
        private void openGLControl1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta > 0)
            {
                _zoom *= 1.1f;
            }
            else
            {
                _zoom /= 1.1f;
            }
            this.openGLControl1.Refresh();
        }
        #endregion
    }
}