commit
1aba94127d
14 changed files with 246 additions and 17 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,161 @@ |
||||
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<Viewport3DTriangleEntity> entities, string outputPath) |
||||
{ |
||||
//分组 |
||||
Dictionary<string, List<Viewport3DTriangleEntity>> feactList = entities |
||||
.Where(entity => entity.PlaneType != PlaneType.Girdle) |
||||
.GroupBy(entity => entity.PlaneCode) |
||||
.ToDictionary(group => group.Key, group => group.ToList()); |
||||
//腰 单组 |
||||
// List<Viewport3DTriangleEntity> waistList = entities |
||||
// .Where(entity => entity.PlaneType == PlaneType.Girdle) |
||||
// .ToList(); |
||||
Dictionary<string, List<Viewport3DTriangleEntity>> gridleList = entities |
||||
.Where(entity => entity.PlaneType == PlaneType.Girdle) |
||||
.GroupBy(entity => entity.PlaneCode) |
||||
.ToDictionary(group => group.Key, group => group.ToList()); |
||||
|
||||
//同一个面只保留外边框(除了腰) |
||||
Dictionary<string, List<Vector3>> resultPoints = new Dictionary<string, List<Vector3>>(); |
||||
|
||||
foreach (var dic in feactList) |
||||
{ |
||||
List<Vector3> tempPoints = new List<Vector3>(); |
||||
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<Vector3>(tempPoints).ToList())); |
||||
} |
||||
|
||||
foreach (var dic in gridleList) |
||||
{ |
||||
List<Vector3> tempPoints = new List<Vector3>(); |
||||
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<Vector3>(tempPoints).ToList())); |
||||
} |
||||
// List<Vector3> selFaceVector = new List<Vector3>(); |
||||
// 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<Vector3> uniqueVertices = new List<Vector3>(); |
||||
Dictionary<Vector3, int> vertexIndexMap = new Dictionary<Vector3, int>(); |
||||
|
||||
// 1. 对每个面生成顶点和面 |
||||
foreach (var face in resultPoints) |
||||
{ |
||||
// 对每个面,获取它的顶点列表 |
||||
List<Vector3> 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<Vector3> faceVertices = face.Value; |
||||
if (!face.Key.StartsWith("11_")) |
||||
{ |
||||
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<Vector3> 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; |
||||
} |
||||
} |
Loading…
Reference in new issue