fix: 修复STL导出

master
Tongg 7 months ago
parent 58202cdd25
commit 495acf9792
  1. 19
      ViewModel/Grading/GradingResultVM.cs
  2. 10
      Views/UserControl/ViewportData/Helper/VideoHelper.cs
  3. 73
      Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs
  4. 8
      Views/UserControl/ViewportData/ViewportData.cs

@ -596,20 +596,21 @@ public class GradingResultVM : BaseViewModel
exportDialog.setValue("Excel File(2/4)"); exportDialog.setValue("Excel File(2/4)");
}); });
ExcelFile(filePath); ExcelFile(filePath);
exportDialog.Dispatcher.Invoke(() => exportDialog.Dispatcher.Invoke(() =>
{ {
exportDialog.setValue("DAT File(3/4)"); exportDialog.setValue("STL File(3/4)");
}); });
await Task.Delay(100);
STLFile(filePath);
await DatFile(filePath);
exportDialog.Dispatcher.Invoke(() => exportDialog.Dispatcher.Invoke(() =>
{ {
exportDialog.setValue("STL File(4/4)"); exportDialog.setValue("DAT File(4/4)");
}); });
await Task.Delay(100);
STLFile(filePath); await DatFile(filePath);
exportDialog.Dispatcher.Invoke(() => exportDialog.Dispatcher.Invoke(() =>
{ {
exportDialog.setValue("Success"); exportDialog.setValue("Success");
@ -864,10 +865,10 @@ public class GradingResultVM : BaseViewModel
//File.Create(filePath + ".dat").Close(); //File.Create(filePath + ".dat").Close();
await ViewportData.SaveAsToVedioFile(filePath + ".mp4"); await ViewportData.SaveAsToVedioFile(filePath + ".mp4");
} }
private void STLFile(string filePath) private async Task STLFile(string filePath)
{ {
//File.Create(filePath + ".stl").Close(); //File.Create(filePath + ".stl").Close();
ViewportData.SaveAsToStlFile(filePath + ".stl"); await ViewportData.SaveAsToStlFile(filePath + ".stl");
} }
private void DataConver(string filePath) private void DataConver(string filePath)
{ {

@ -130,9 +130,9 @@ public class VideoHelper
} }
} }
var dicName = Path.GetDirectoryName(outputPath); // var dicName = Path.GetDirectoryName(outputPath);
var fileName = Path.GetFileNameWithoutExtension(outputPath); // var fileName = Path.GetFileNameWithoutExtension(outputPath);
Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(outputPath, fileName + ".dat"); // Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(outputPath, fileName + ".dat");
} }
finally finally
{ {
@ -185,7 +185,7 @@ public class VideoHelper
// 使用 Dispatcher.Invoke 来确保 UI 操作在主线程中执行 // 使用 Dispatcher.Invoke 来确保 UI 操作在主线程中执行
var encoder = Application.Current.Dispatcher.Invoke(() => CutPng(viewport)); var encoder = Application.Current.Dispatcher.Invoke(() => CutPng(viewport));
result.Add(encoder); result.Add(encoder);
Thread.Sleep(50); // 模拟处理过程 Thread.Sleep(25); // 模拟处理过程
} }
return result; return result;
@ -206,7 +206,7 @@ public class VideoHelper
ViewportHelperPro.RotateModel(new Vector3D(0,-1,0)); ViewportHelperPro.RotateModel(new Vector3D(0,-1,0));
}); });
await Task.Delay(5000); await Task.Delay(7000);
await Application.Current.Dispatcher.InvokeAsync(() => await Application.Current.Dispatcher.InvokeAsync(() =>
{ {
ViewportHelperPro.RotateModel(new Vector3D(-1, 0, 0)); ViewportHelperPro.RotateModel(new Vector3D(-1, 0, 0));

@ -1,5 +1,6 @@
using System.Collections.Frozen; using System.Collections.Frozen;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing.Text; using System.Drawing.Text;
using System.IO; using System.IO;
using System.Windows; using System.Windows;
@ -7,6 +8,7 @@ using System.Windows.Media;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D; using System.Windows.Media.Media3D;
using System.Windows.Threading;
using HelixToolkit.Wpf.SharpDX; using HelixToolkit.Wpf.SharpDX;
using SharpDX; using SharpDX;
using SharpDX.Direct3D11; using SharpDX.Direct3D11;
@ -192,6 +194,7 @@ public class ViewportHelperPro
writer.WriteLine("solid exportedModel"); writer.WriteLine("solid exportedModel");
foreach (var model in viewport.Items.OfType<MeshGeometryModel3D>()) foreach (var model in viewport.Items.OfType<MeshGeometryModel3D>())
{ {
if (model.Geometry is HelixToolkit.Wpf.SharpDX.Geometry3D geometry) if (model.Geometry is HelixToolkit.Wpf.SharpDX.Geometry3D geometry)
{ {
var positions = geometry.Positions; var positions = geometry.Positions;
@ -227,7 +230,73 @@ public class ViewportHelperPro
writer.WriteLine("endsolid exportedModel"); writer.WriteLine("endsolid exportedModel");
} }
} }
/// <summary>
/// 导出模型
/// </summary>
/// <param name="viewport"></param>
/// <param name="filePath"></param>
public static async Task ExportModelsToStlASync( string filePath)
{
Viewport3DX viewport = ViewportManager.GetViewport3D();
// 创建一个集合来存储几何信息
List<Tuple<IList<Vector3>, IList<int>>> geometries = new List<Tuple<IList<Vector3>, IList<int>>>();
// 在 UI 线程中收集几何信息
await Application.Current.Dispatcher.InvokeAsync(() =>
{
foreach (var model in viewport.Items.OfType<MeshGeometryModel3D>())
{
if (model.Geometry is HelixToolkit.Wpf.SharpDX.Geometry3D geometry)
{
geometries.Add(new Tuple<IList<Vector3>, IList<int>>(geometry.Positions, geometry.Indices));
}
}
});
// 在后台线程中处理几何信息并写入 STL 文件
await Task.Run(() =>
{
using (StreamWriter writer = new StreamWriter(filePath))
{
writer.WriteLine("solid exportedModel");
foreach (var geometry in geometries)
{
var positions = geometry.Item1;
var indices = geometry.Item2;
// 每三个索引构成一个三角形
for (int i = 0; i < indices.Count; i += 3)
{
int index0 = indices[i];
int index1 = indices[i + 1];
int index2 = indices[i + 2];
var p0 = positions[index0];
var p1 = positions[index1];
var p2 = positions[index2];
// 计算法线
var normal = CalculateNormal(p0, p1, p2);
// 写入三角形信息到 STL 文件
writer.WriteLine($" facet normal {normal.X} {normal.Y} {normal.Z}");
writer.WriteLine(" outer loop");
writer.WriteLine($" vertex {p0.X} {p0.Y} {p0.Z}");
writer.WriteLine($" vertex {p1.X} {p1.Y} {p1.Z}");
writer.WriteLine($" vertex {p2.X} {p2.Y} {p2.Z}");
writer.WriteLine(" endloop");
writer.WriteLine(" endfacet");
}
}
// 写入 STL 文件结束
writer.WriteLine("endsolid exportedModel");
}
}).ConfigureAwait(false);
}
/// <summary> /// <summary>
/// 通过三角形实体集合生成每个面的边框线 /// 通过三角形实体集合生成每个面的边框线
/// </summary> /// </summary>
@ -473,7 +542,7 @@ public class ViewportHelperPro
/// <param name="axis">中心</param> /// <param name="axis">中心</param>
/// <param name="hasLine">是否包含线</param> /// <param name="hasLine">是否包含线</param>
/// <param name="speed">旋转时间 秒</param> /// <param name="speed">旋转时间 秒</param>
public static void RotateModel(Vector3D axis, bool hasLine = true, int speed = 5, int to = 360) public static void RotateModel(Vector3D axis, bool hasLine = true, int speed = 7, int to = 360)
{ {
// 设置旋转的中心点和旋转轴 // 设置旋转的中心点和旋转轴
var rotateTransform = new RotateTransform3D(); var rotateTransform = new RotateTransform3D();

@ -141,16 +141,16 @@ public class ViewportData
} }
public bool SaveAsToStlFile(string filename) public async Task SaveAsToStlFile(string filename)
{ {
try try
{ {
ViewportHelperPro.ExportModelsToStl(null, filename); await ViewportHelperPro.ExportModelsToStlASync(filename);
return true; return ;
} }
catch catch
{ {
return false; return ;
} }
} }

Loading…
Cancel
Save