【C#+OpenTK】减材制造-铣削仿真

d32d4b37b244732891e69d7236c03853.png主界面

视频演示1

视频演示2

b96d659a287994421ca8b8524230c68b.png程序框架

部分代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;


using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Geometric2.RasterizationClasses;
using OpenTK.Graphics.OpenGL4;
using Geometric2.MatrixHelpers;
using Geometric2.ModelGeneration;
using System.Numerics;
using OpenTK;
using Geometric2.Helpers;
using System.Diagnostics;
using System.Threading;
using System.Drawing;
using Geometric2.Global;
using System.Xml;
using System.Linq;
using Geometric2.Models;


namespace Geometric2
{
    public partial class Form1 : Form
    {
        Thread progressthread;
        Thread glthread;
        public Form1()
        {
            InitializeComponent();
            InitSolution();
            glthread = new Thread(() =>
            {
                while (true)
                {
                    glControl1.Invalidate();//gl更新
                    Thread.Sleep(16);
                }
            });


            glthread.Start();//更新GL线程
            FormClosing += new FormClosingEventHandler(Form1_Closing);
            coursor = new Coursor();//鼠标
            millModel = new MillModel(dataModel.Width, dataModel.Height, dataModel.Altitude, dataModel.Divisions_X, dataModel.Divisions_Y, simulationTick, percentCompleted, nonCuttingPart);//铣削元素
            coursor.CoursorMode = CoursorMode.Auto;//鼠标自动模式
            transformCenterLines.selectedElements = SelectedElements;//变换的中心线:选中元素
            this.glControl1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseWheel);//鼠标滚轮事件处理函数
        }
        //关闭窗口时关闭线程
        private void Form1_Closing(object sender,EventArgs e)
        {
            progressthread.Abort();
            glthread.Abort();
            //if (this.progressthread.ThreadState== System.Threading.ThreadState.Running)
            //{
            //    progressthread.Abort();


            //}


            Application.Exit();


        }
        //窗体加载
        private void Form1_Load(object sender, EventArgs e)
        {   //开启进度条线程
             progressthread = new Thread(() =>
            {
                while (true)
                {
                    this.Invoke((MethodInvoker)delegate { 
                        progressBar.Value = percentCompleted[0];//更新进度条
                        if (nonCuttingPart[0] != 0)//无铣削零件
                        {
                            errorLabel.Text = "ERROR: MILLING WITH A NON-CUTTING PART";
                            nonCuttingPart[0] = 0;
                        }
                    });
                    if (percentCompleted[0] == 100)//完成后,重置
                    {
                        percentCompleted[0] = 0;
                    }


                    Thread.Sleep(50);
                }
            });
            progressthread.Start();//开启进度条更新线程
            // UI 初始化
            cameraLightCheckBox.Checked = true;
            radiousTextBox.Text = "5.0";
            drillHeightTextBox.Text = "50";
            normalRadioButton.Checked = true;
            drillButton.Enabled = false;
        }


        private List<Vector3> drillPositions;//铣削路径点
        private Shader _shader;//路径线着色器
        private Shader _millshader;//铣削着色器
        private Camera _camera;//相机
        private Coursor coursor;//鼠标渲染
        private MillModel millModel;//铣削模型
        public InitializeDataModel dataModel;//初始数据模型
        private bool cameraLight = true;//相机灯光
        DrillType drillType = DrillType.Normal;//铣削模拟速度类型:正常  
        CutterType cutterType = CutterType.Spherical;//球头铣刀
        int radious = 50;//半径
        int drillHeight = 50;//铣刀高度
        int[] simulationTick = new int[] { 0 };//仿真快慢
        int[] percentCompleted = new int[] { 0 };//仿真百分比
        int[] nonCuttingPart = new int[] { 0 };//无铣削零件




        private XyzLines xyzLines = new XyzLines();X Y Z轴 无限长直线
        private DrillingLines drillingLines;//铣削路径
        private List<Element> Elements = new List<Element>();//元素集合:铣削路径 集合
        private List<Element> SelectedElements = new List<Element>();//选中元素
        DrawingStatus drawingStatus = DrawingStatus.No;//绘制状态
        private TransformCenterLines transformCenterLines = new TransformCenterLines();//变换的中心线


        int prev_xPosMouse = -1, prev_yPosMouse = -1;//上一鼠标位置
        int torusNumber;//环数
        //加载路径文件
        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "All files (*.*)|*.*";
            openFileDialog.FilterIndex = 2;
            openFileDialog.Title = "Select Paths File";
            openFileDialog.RestoreDirectory = true;
            string fileName = "";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                fileName = openFileDialog.FileName;
                List<string> file = new List<string>();//行列表
                drillPositions = new List<Vector3>();
                foreach (string line in System.IO.File.ReadLines(fileName))
                {
                    file.Add(line);
                }


                foreach (var line in file)//遍历行,并解析。得到铣削路径坐标
                {
                    string afterX = line.Split('X')[1];
                    string X = afterX.Split('Y')[0];
                    string afterY = afterX.Split('Y')[1];
                    string Y = afterY.Split('Z')[0];
                    string Z = afterY.Split('Z')[1];


                    float _x, _y, _z;
                    if (float.TryParse(X, out _x) && float.TryParse(Y, out _y) && float.TryParse(Z, out _z))
                    {
                        drillPositions.Add(new Vector3(_x, _z, -_y));//x,y,z路径点。
                        if(_z < 0)
                        {
                            MessageBox.Show("GIONG TO DRILL UNDER SURFACE");
                        }
                    }
                }


                drillingLines = new DrillingLines(drillPositions);//铣削路径
                Element elToRemove = null;//铣削路径线,找到后删除
                foreach(var el in Elements)
                {
                    if(el is DrillingLines)
                    {
                        elToRemove = el;//找到铣削路径线
                    }
                }


                if(elToRemove != null)//存在铣削路径线
                {
                    Elements.Remove(elToRemove);//移除路径元素
                    drillingLineCheckBox.Checked = false;//不显示路径线条
                }


                string fileExt = fileName.Split('.').LastOrDefault();//文件后缀
                if(fileExt.Length == 3)// kxx   xx:为铣刀尺寸代号
                {
                    char drill = fileExt[0];
                    if(drill == 'k')
                    {
                        cutterType = CutterType.Spherical;// 后缀含k,球头铣刀
                    }
                    else
                    {
                        cutterType = CutterType.Flat;//端铣刀
                    }


                    string size = fileExt[1].ToString() + fileExt[2].ToString();
                    int r;
                    if (int.TryParse(size, out r))//铣刀尺寸代号
                    {
                        radious = r * 10;//半径x10   
                    }
                    else
                    {
                        radious = 50;//默认半径50
                    }
                }
                else
                {
                    cutterType = CutterType.Spherical;//默认球头铣刀
                    radious = 50;//默认直径50
                }


                if(cutterType == CutterType.Spherical)
                {
                    sphericalRadioButton.Checked = true;//勾选球头铣刀复选框
                }
                else
                {
                    flatRadioButton.Checked = true;//勾选端铣刀复选框
                }


                radiousTextBox.Text = (radious / 10.0f).ToString();//显示半径代号
                drillButton.Enabled = true;//铣削按钮可用


                Elements.Add(drillingLines);//将新加载的铣削路径添加到 元素集合
                drillingLines.CreateGlElement(_shader);//创建铣削路径线GL元素:着色器—  _shader
            }
        }
        //新建解决方案:设置基板尺寸
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            InitSolution();
        }
        //勾选绘制铣削路径线
        private void drillingLineCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (drillingLines != null)
            {
                drillingLines.DrawPolyline = drillingLineCheckBox.Checked;
            }
        }
        //相机光照
        private void cameraLightCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            cameraLight = cameraLightCheckBox.Checked;
        }
        //半径 文本框设置
        private void radiousTextBox_TextChanged(object sender, EventArgs e)
        {
            float r;
            if (float.TryParse(radiousTextBox.Text, out r))
            {
                radious = (int)(r * 10);//半径是设置值的10倍
                if (radiousTextBox.Text.Contains(".") && radiousTextBox.Text.Split('.').LastOrDefault().Length > 1 || radiousTextBox.Text.Split('.').Length > 2)
                {
                    radiousTextBox.Text = (radious / 10.0f).ToString();
                }
            }
            else
            {
                radiousTextBox.Text = (radious / 10.0f).ToString();//解析文本框失败:重置为初始 50/10=5
            }
        }
        //铣削仿真
        private void drillButton_Click(object sender, EventArgs e)
        {
            millModel.DrillAll(drillingLines.drillPoints, cutterType, drillType, radious, drillHeight);
        }
        //正常速度仿真
        private void normalRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            drillType = DrillType.Normal;
        }
        //快速仿真
        private void quickRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            drillType = DrillType.Fast;
        }
        //并行线程仿真
        private void parallelRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            drillType = DrillType.Parallel;
        }
        //球头铣刀类型
        private void sphericalRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            cutterType = CutterType.Spherical;
        }
        //端铣刀
        private void flatRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            cutterType = CutterType.Flat;
        }
        //清空
        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(millModel != null && millModel.topLayer != null)//
            {
                for(int i=0;i<dataModel.Width;i++)
                {
                    for(int j=0;j<dataModel.Height;j++)
                    {
                        millModel.topLayer[i, j] = dataModel.Altitude;// 重置[i,j]坐标处顶层高度
                    }
                }
            }
        }


        private void progressBar_Click(object sender, EventArgs e)
        {
        }
        //修改仿真步长
        private void simulationTickTrackBar_Scroll(object sender, EventArgs e)
        {
            simulationTick[0] = simulationTickTrackBar.Value;
        }
        //修改铣刀高度
        private void drillHeightTextBox_TextChanged(object sender, EventArgs e)
        {
            float drillH;
            if (float.TryParse(drillHeightTextBox.Text, out drillH))
            {
                drillHeight = (int)(drillH * 10);
                if (drillHeightTextBox.Text.Contains(".") && drillHeightTextBox.Text.Split('.').LastOrDefault().Length > 1 || drillHeightTextBox.Text.Split('.').Length > 2)
                {
                    drillHeightTextBox.Text = (drillHeight / 10.0f).ToString();
                }
            }
            else
            {
                drillHeightTextBox.Text = (drillHeight / 10.0f).ToString();
            }
        }
        //初始化解决方案:设置基板尺寸
        private void InitSolution()
        {
            dataModel = new InitializeDataModel();//初始化数据模型
            InitializeData initializeData = new InitializeData(dataModel);//实例化初始化数据对话框
            initializeData.ShowDialog();//显示对话框


            if(dataModel.Width == -1)//宽度需非-1
            {
                Environment.Exit(Environment.ExitCode);
            }
            else//显示修改后的数据
            {
                widthLabelValue.Text = (dataModel.Width / 10.0f).ToString() + " mm";
                heightLabelValue.Text = (dataModel.Height / 10.0f).ToString() + " mm";
                altitudeLabelValue.Text = (dataModel.Altitude * 10.0f).ToString() + " mm";
                divisionsXLabelValue.Text = (dataModel.Divisions_X).ToString();
                divisionsYLabelValue.Text = (dataModel.Divisions_Y).ToString();
            }
        }
    }
}

The End

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值