diff --git a/SparkClient.sln.DotSettings.user b/SparkClient.sln.DotSettings.user
index 79d18e2..117353a 100644
--- a/SparkClient.sln.DotSettings.user
+++ b/SparkClient.sln.DotSettings.user
@@ -15,6 +15,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
@@ -28,6 +29,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
@@ -68,6 +70,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
@@ -77,6 +80,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
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..91b7c64
--- /dev/null
+++ b/Views/UserControl/ViewportData/Helper/ObjExporter.cs
@@ -0,0 +1,140 @@
+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) => GetAngle(v1, center).CompareTo(GetAngle(v2, center)));
+
+ // 正面:按顺时针顺序输出
+ sb.Append("f");
+ foreach (var vertex in faceVertices)
+ {
+ sb.Append($" {vertexIndexMap[vertex] + 1}");
+ }
+ sb.AppendLine();
+
+ // 反面:按逆时针顺序输出(反转顶点顺序)
+ sb.Append("f");
+ for (int i = faceVertices.Count - 1; i >= 0; i--)
+ {
+ sb.Append($" {vertexIndexMap[faceVertices[i]] + 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);
+ }
+
+ private static float GetAngle(Vector3 vertex, Vector3 center)
+ {
+ // 计算顶点与中心的方向向量
+ Vector3 direction = vertex - center;
+
+ // 在XY平面上计算角度
+ float angle = (float)Math.Atan2(direction.Y, direction.X); // 返回的是弧度,[-π, π]
+
+ // 如果你想要角度范围 [0, 2π],可以做如下处理
+ if (angle < 0)
+ {
+ angle += MathF.PI * 2;
+ }
+
+ return angle;
+ }
+}
\ No newline at end of file