微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何解决 OpenTK 中的致命执行引擎错误?

如何解决如何解决 OpenTK 中的致命执行引擎错误?

我正在尝试使用 OpenTK 开发程序。这个程序的目的是加载一个 ASCII 格式的 STL(立体光刻)文件,然后在 OpenTK 中渲染它,并使用名称堆栈跟踪所选对象。在这个程序中,我使用鼠标右键单击来获取所选对象。

STL文件的简要说明在这里https://en.wikipedia.org/wiki/STL_(file_format)

在我的代码中,我使用了 2 个 STL 文件。第一个 STL 文件一个简单的几何图形(文件大小为 8 kb)。第二个 STL 文件一个复杂的几何图形(文件大小 1167 kb)。当我使用第一个 STL 文件并运行我的代码时,当我使用鼠标右键单击功能时,它运行良好。

但是,当我使用第二个 STL 文件并运行我的代码(然后单击鼠标右键)时,我得到了这个致命的执行引擎错误异常。我不确定为什么会收到此错误。是不是因为文件太大了?但是我可以将第二个文件渲染到 OpenTK 中。是不是因为我必须在这里设置足够大的buff大小才能避免这种异常?

你知道为什么会这样吗?有什么方法可以避免这个错误/异常?

这两个 STL 文件链接在这里https://drive.google.com/drive/folders/1v9bUzqVx1a1_KbnSXCQ5LREoQaAFUn2D?usp=sharing

这是我的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;

namespace OpenTK3D
{
    public class Game3D
    {
        private GameWindow window;
        private float zoom;
        private bool hasRotationStarted;
        private int startX;
        private int startY;
        private float xRotAngle;
        private float yRotAngle;

        private bool hasPanningStarted;
        private float xTrans;
        private float yTrans;
        private int BUFSIZE = 512;

        private string filePath = @"C:\Users\mpelmt\Desktop\ISF forming direction optimization\verify_65_40_yForming_noFlange.STL";
        private double angleLimit = 60;

        public Game3D(GameWindow wd)
        {
            this.window = wd;
            var zBoundary = zBoundaryValue(filePath);
            hasRotationStarted = false;
            startX = 0;
            startY = 0;
            xRotAngle = 28;
            yRotAngle = -45;
            zoom = -(float)zBoundary;

            hasPanningStarted = false;
            xTrans = 0;
            yTrans = 0;

            start();
        }

        public void start()
        {
            window.Load += loaded;
            window.Resize += resize;           
            window.RenderFrame += renderFrame;
            window.MouseDown += mouseLeftPress;
            window.MouseUp += mouseRelease;
            window.MouseMove += mouseDragEvent;
            window.MouseWheel += MouseWheelHandler;
            window.MouseDown += wheelPressEvent;
            window.MouseUp += wheelReleaseEvent;
            window.MouseMove += wheelDragEvent;
            window.MouseDown += select;
            window.Run(1.0 / 60.0);
        }

        private List<double> getAllSTLData(string path)
        {
            string[] text = System.IO.File.ReadAllLines(path);
            List<double> allData = new List<double>();
            foreach (var line in text)
            {
                if (line.Contains("facet normal"))
                {
                    var normal = Array.ConvertAll(line.Remove(0,16).Split(' '),double.Parse);
                    allData.AddRange(normal);
                }

                if (line.Contains("vertex"))
                {
                    var position = Array.ConvertAll(line.Remove(0,double.Parse);
                    allData.AddRange(position);
                }
            }
            return allData;
        }

        private Dictionary<int,List<double>> getAllFacets(string path)
        {
            var allSTLData = getAllSTLData(path);
            var allFacet = new Dictionary<int,List<double>>();
            for (int i = 0; i < (allSTLData.Count) / 12; i++)
            {
                allFacet.Add(i + 1,allSTLData.GetRange(12 * i,12));
            }
            return allFacet;
        }

        private double yBoundaryValue(string path)
        {
            var allFacets = getAllFacets(path);
            var listofY = new List<double>();
            foreach (keyvaluePair<int,List<double>> kp in allFacets)
            {
                var vertex = kp.Value.GetRange(3,9);
                listofY.Add(vertex[1]);
                listofY.Add(vertex[4]);
                listofY.Add(vertex[7]);
            }
            return listofY.Max() - listofY.Min();
        }

        private double xBoundaryValue(string path)
        {
            var allFacets = getAllFacets(path);
            var listofX = new List<double>();
            foreach (keyvaluePair<int,9);
                listofX.Add(vertex[0]);
                listofX.Add(vertex[3]);
                listofX.Add(vertex[6]);
            }
            return listofX.Max() - listofX.Min();
        }

        private double zBoundaryValue(string path)
        {
            var allFacets = getAllFacets(path);
            var listofZ = new List<double>();
            foreach (keyvaluePair<int,9);
                listofZ.Add(vertex[2]);
                listofZ.Add(vertex[5]);
                listofZ.Add(vertex[8]);
            }
            return listofZ.Max() - listofZ.Min();
        }


        private List<double> getAngleRangeWithinLimit(double angleLimit)
        {
            var result = new List<double>();
            var section = (int)angleLimit / 5;
            var remain = angleLimit % 5;

            for (int i = 0; i < section; i++)
            {
                result.Add(5 * i);
                result.Add(5 * i + 5);
            }

            if (remain != 0)
            {
                result.Add(result.Last());
                result.Add(result.Last() + remain);
            }
            return result;
        }

        public Dictionary<int,List<double>> pickSelectFacetsByAngleInYForm(string path,double angleLimit)
        {
            var result = new Dictionary<int,List<double>>();
            var allFacets = getAllFacets(path);
            var angleRange = getAngleRangeWithinLimit(angleLimit);

            foreach (keyvaluePair<int,List<double>> kp in allFacets)
            {
                var data = kp.Value;
                var id = kp.Key;
                var tempList = new List<double>();
                var angle = Math.Acos(Math.Abs(data[1])) * 180 / (Math.PI);
                for (int i = 0; i < angleRange.Count / 2; i++)
                {
                    if (angle >= angleLimit)
                    {
                        tempList.AddRange(data);
                        tempList.Add(angleLimit + 1);
                        break;
                    }

                    else if (angle >= angleRange[2 * i] && angle <= angleRange[2 * i + 1])
                    {
                        tempList.AddRange(data);
                        tempList.Add(angleRange[2 * i + 1]);
                        break;
                    }
                }
                result.Add(id,tempList);
            }
            return result;
        }

        public void renderColorPlotYForm(string path,double angleLimit)
        {
            var plotData = pickSelectFacetsByAngleInYForm(path,angleLimit);
            foreach (keyvaluePair<int,List<double>> kv in plotData)
            {
                var id = kv.Key;
                var data = kv.Value;
                GL.Begin(BeginMode.Triangles);
                var colorRange = data.Last();

                if (colorRange == 5)
                {
                    // green
                    GL.Color3(0.0,1.0,0.0);
                }

                if (colorRange == angleLimit + 1)
                {
                    //red
                    GL.Color3(1.0,0.0,0.0);
                }

                if (colorRange == 30)
                {
                    // yellow
                    GL.Color3(1.0,0.0);
                }

                if (colorRange < 30 && colorRange > 5)
                {
                    var diff = 30 - colorRange;
                    var ratio = diff / 25;
                    GL.Color3(1 - ratio,1,0);
                }

                if (colorRange > 30 && colorRange < angleLimit + 1)
                {
                    var ratio = (angleLimit - colorRange) / angleLimit;
                    GL.Color3(1,1 - ratio,0);
                }

                var listofVertex = data.GetRange(3,9);
                for (int i = 0; i < 3; i++)
                {
                    var vertex = listofVertex.GetRange(3 * i,3);
                    GL.Vertex3(vertex[0],vertex[1],vertex[2]);
                }

                GL.End();
            }
        }

        public void pickSelectColorPlotYForm(string path,List<double>> kv in plotData)
            {
                var id = kv.Key;
                var data = kv.Value;
                GL.LoadName(id);
                GL.Begin(BeginMode.Triangles);
                var colorRange = data.Last();

                if (colorRange == 5)
                {
                    // green
                    GL.Color3(0.0,vertex[2]);
                }

                GL.End();
            }
        }


        public void loaded(object o,EventArgs e)
        {
            GL.ClearColor(0.0f,0.0f,0.0f);
            GL.Enable(EnableCap.DepthTest);
        }

        public void renderFrame(object o,EventArgs e)
        {
            var xBoundary = xBoundaryValue(filePath);
            var yBoundary = yBoundaryValue(filePath);
            var zBoundary = zBoundaryValue(filePath);
            var xCen = xBoundary / 2;
            var yCen = yBoundary / 2;
            var zCen = zBoundary / 2;

            GL.LoadIdentity();
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            GL.Translate(xTrans,yTrans,zoom*3);
            GL.Rotate(xRotAngle,0);
            GL.Rotate(yRotAngle,0);
            renderColorPlotYForm(filePath,angleLimit);

            window.SwapBuffers();
        }

        public void resize(object o,EventArgs e)
        {
            var zBoundary = zBoundaryValue(filePath);
            GL.Viewport(0,window.Width,window.Height);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            // the fov must be radian
            var matrix = Matrix4.CreatePerspectiveFieldOfView(45.0f*(MathHelper.Pi)/180,window.Width / window.Height,1.0f,(float)zBoundary * (float)zBoundary);
            GL.LoadMatrix(ref matrix);
            GL.MatrixMode(MatrixMode.Modelview);
        }

        private void processHits(int hits,int[] buffer)
        {
            Console.WriteLine("hit: {0}",hits);

            if (hits > 0)
            {
                int choose = buffer[3];
                int depth = buffer[1];
                for (int i = 0; i < hits; i++)
                {
                    if (buffer[i * 4 + 1] < depth)
                    {
                        choose = buffer[i * 4 + 3];
                        depth = buffer[i * 4 + 1];
                    }
                }
                Console.WriteLine("choosen: {0}",choose);
            }
        }

        private void gluPickMatrix(double x,double y,double deltax,double deltay,int[] viewport)
        {
            if (deltax <= 0 || deltay <= 0)
            {
                return;
            }

            GL.Translate((viewport[2] - 2 * (x - viewport[0])) / deltax,(viewport[3] - 2 * (y - viewport[1])) / deltay,0);
            GL.Scale(viewport[2] / deltax,viewport[3] / deltay,1.0);
        }

        public void select(object o,MouseEventArgs e)
        {
            var zBoundary = zBoundaryValue(filePath);
            var mouse = Mouse.GetState();
            if (mouse[MouseButton.Right])
            {
                var buffer = new int[BUFSIZE];
                var viewPort = new int[4];
                int hits;
                GL.GetInteger(GetPName.Viewport,viewPort);
                GL.SelectBuffer(BUFSIZE,buffer);
                GL.RenderMode(RenderingMode.Select);

                GL.InitNames();
                GL.PushName(0);

                GL.MatrixMode(MatrixMode.Projection);
                GL.Pushmatrix();
                GL.LoadIdentity();

                gluPickMatrix(e.Mouse.X,viewPort[3] - e.Mouse.Y,5.0,viewPort);

                var matrix = Matrix4.CreatePerspectiveFieldOfView(45.0f * (MathHelper.Pi) / 180,(float)zBoundary * (float)zBoundary);
                GL.MultMatrix(ref matrix);
                GL.MatrixMode(MatrixMode.Modelview);

                pickSelectColorPlotYForm(filePath,angleLimit);

                   
                GL.MatrixMode(MatrixMode.Projection);
                GL.PopMatrix();
                GL.MatrixMode(MatrixMode.Modelview);

                GL.Flush();
                hits = GL.RenderMode(RenderingMode.Render);
                processHits(hits,buffer);
            }
        }

        public void mouseLeftPress(object sender,MouseEventArgs e)
        {
            if (e.Mouse.LeftButton == ButtonState.pressed)
            {
                hasRotationStarted = true;
                startX = e.Mouse.X;
                startY = e.Mouse.Y;
            }
        }

        public void mouseRelease(object sender,MouseEventArgs e)
        {
            if (e.Mouse.LeftButton == ButtonState.Released)
            {
                hasRotationStarted = false;
            }
        }

        public void mouseDragEvent(object sender,MouseEventArgs e)
        {
            if (hasRotationStarted == true && e.Mouse.X != e.Mouse.Y)
            {
                xRotAngle = xRotAngle + (e.Mouse.Y - startY);
                yRotAngle = yRotAngle + (e.Mouse.X - startX);
                startX = e.Mouse.X;
                startY = e.Mouse.Y;
            }
        }

        public void MouseWheelHandler(object sender,MouseWheelEventArgs e)
        {
            var xBoundary = xBoundaryValue(filePath);

            if (e.Delta > 0)
            {
                zoom += 0.1f * (float)xBoundary;
            }

            if (e.Delta < 0)
            {
                zoom -= 0.1f * (float)xBoundary;
            }
        }

        public void wheelPressEvent(object sender,MouseEventArgs e)
        {
            if (e.Mouse.MiddleButton == ButtonState.pressed)
            {
                hasPanningStarted = true;
                startX = e.Mouse.X;
                startY = e.Mouse.Y;
            }
        }

        public void wheelReleaseEvent(object sender,MouseEventArgs e)
        {
            if (e.Mouse.MiddleButton == ButtonState.Released)
            {
                hasPanningStarted = false;
            }
        }

        public void wheelDragEvent(object sender,MouseEventArgs e)
        {
            if (hasPanningStarted == true)
            {
                xTrans = xTrans + 2 * (e.Mouse.X - startX);
                yTrans = yTrans - 2 * (e.Mouse.Y - startY);
                startX = e.Mouse.X;
                startY = e.Mouse.Y;
            }
        }
    }
}

这里是主要功能

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;

namespace OpenTK3D
{
    class Program
    {
        static void Main(string[] args)
        {
            var window = new GameWindow(500,500);
            var gm = new Game3D(window);
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Press enter to finish...");
            Console.ReadLine();

        }
    }
}

这是我使用第一个 STL 文件运行我的代码时的结果(它工作正常):

The initial result using first STL file

当我使用第二个 STL 文件运行我的代码时,我得到了这个致命的执行引擎错误

Fatal Execution Engine Error

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。