如何解决如何解决 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 文件运行我的代码时的结果(它工作正常):
当我使用第二个 STL 文件运行我的代码时,我得到了这个致命的执行引擎错误:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。