From 55241d544b6ca7324f03a8680971c0c66903632b Mon Sep 17 00:00:00 2001 From: tongg Date: Sat, 1 Feb 2025 20:44:52 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20OBJ=E6=96=87=E4=BB=B6=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Views/UserControl/Viewport3D.xaml.cs | 6 +- .../ViewportData/Helper/ObjExporter.cs | 116 ++++++++++++++++++ 2 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 Views/UserControl/ViewportData/Helper/ObjExporter.cs diff --git a/Views/UserControl/Viewport3D.xaml.cs b/Views/UserControl/Viewport3D.xaml.cs index afdbbc8..e1effc6 100644 --- a/Views/UserControl/Viewport3D.xaml.cs +++ b/Views/UserControl/Viewport3D.xaml.cs @@ -17,6 +17,7 @@ using SharpDX.Direct3D11; using SharpDX.DXGI; using MathNet.Numerics; using System.Windows.Media; +using ObjExporter = SparkClient.Views.UserControl.ViewportData.Helper.ObjExporter; namespace SparkClient.Views.UserControl; @@ -46,7 +47,7 @@ public partial class Viewport3D ViewportManager.LoadModelByEntities(new List()); #if DEBUG #else - BtnShow3DView.Visibility = Visibility.Hidden; + // BtnShow3DView.Visibility = Visibility.Hidden; #endif //选项初始化 显示-后端-管理类 一致 @@ -218,7 +219,8 @@ public partial class Viewport3D ViewportManager.DoubleClickSelect = !false; break; case "BtnShow3DView": - UnityHelper.GenerateRender(ViewportManager.ViewportTriangle.First().TriangleCode, "123"); + ObjExporter.ExportToObj2(ViewportManager.ViewportTriangle, @"D:\id03.obj"); + //UnityHelper.GenerateRender(ViewportManager.ViewportTriangle.First().TriangleCode, "123"); break; } diff --git a/Views/UserControl/ViewportData/Helper/ObjExporter.cs b/Views/UserControl/ViewportData/Helper/ObjExporter.cs new file mode 100644 index 0000000..82417d2 --- /dev/null +++ b/Views/UserControl/ViewportData/Helper/ObjExporter.cs @@ -0,0 +1,116 @@ +using System.IO; +using System.Text; +using SharpDX; +using SparkClient.Views.UserControl.ViewportData.Entity; +using SparkClient.Views.UserControl.ViewportData.Enum; + +namespace SparkClient.Views.UserControl.ViewportData.Helper; + +public class ObjExporter +{ + + public static void ExportToObj2(List entities, string outputPath) + { + //分组 + Dictionary> feactList = entities + .Where(entity => entity.PlaneType != PlaneType.Girdle) + .GroupBy(entity => entity.PlaneCode) + .ToDictionary(group => group.Key, group => group.ToList()); + //腰 单组 + List waistList = entities + .Where(entity => entity.PlaneType == PlaneType.Girdle) + .ToList(); + + //同一个面只保留外边框(除了腰) + Dictionary> resultPoints = new Dictionary>(); + + foreach (var dic in feactList) + { + List tempPoints = new List(); + foreach (var entity in dic.Value) + { + tempPoints.Add(entity.Point1); + tempPoints.Add(entity.Point2); + tempPoints.Add(entity.Point3); + } + resultPoints.Add(dic.Key, ViewportHelperPro.VectorClockwiseSort(new HashSet(tempPoints).ToList())); + } + List selFaceVector = new List(); + if (waistList.Count > 0) + { + foreach (var entity in waistList) + { + selFaceVector.Add(entity.Point1); + selFaceVector.Add(entity.Point2); + selFaceVector.Add(entity.Point3); + } + } + resultPoints.Add("yao", selFaceVector); + + + StringBuilder sb = new StringBuilder(); + + // 顶点列表 + List uniqueVertices = new List(); + Dictionary vertexIndexMap = new Dictionary(); + + // 1. 对每个面生成顶点和面 + foreach (var face in resultPoints) + { + // 对每个面,获取它的顶点列表 + List faceVertices = face.Value; + + // 去重顶点 + foreach (var vertex in faceVertices) + { + if (!vertexIndexMap.ContainsKey(vertex)) + { + vertexIndexMap[vertex] = uniqueVertices.Count; + uniqueVertices.Add(vertex); + } + } + } + + // 2. 写入顶点数据 + foreach (var vertex in uniqueVertices) + { + sb.AppendLine($"v {vertex.X} {vertex.Y} {vertex.Z}"); + } + + // 3. 写入每个面(f行) + foreach (var face in resultPoints) + { + sb.AppendLine($"# Face: {face.Key}"); + + // 获取面上的所有顶点并排序 + List faceVertices = face.Value; + // Vector3 center = GetCenterOfVertices(faceVertices); + // faceVertices.Sort((v1, v2) => v1.AngleWithCenter(center).CompareTo(v2.AngleWithCenter(center))); + // center + // 输出面 + sb.Append("f"); + foreach (var vertex in faceVertices) + { + // 获取顶点的索引,OBJ格式从1开始 + sb.Append($" {vertexIndexMap[vertex] + 1}"); + } + sb.AppendLine(); + } + + // 4. 写入文件 + File.WriteAllText(outputPath, sb.ToString()); + } + + // 计算一组顶点的中心点(用于排序) + private static Vector3 GetCenterOfVertices(List vertices) + { + float centerX = 0, centerY = 0, centerZ = 0; + foreach (var vertex in vertices) + { + centerX += vertex.X; + centerY += vertex.Y; + centerZ += vertex.Z; + } + return new Vector3(centerX / vertices.Count, centerY / vertices.Count, centerZ / vertices.Count); + } +} \ No newline at end of file