ComputerGraphics/20210129/doc/zxq/NwGeoExporter/NwGeoExporter/Models/Mesh.cs
2021-02-28 11:38:29 +08:00

143 lines
4.8 KiB
C#

using Autodesk.Navisworks.Api.Interop.ComApi;
using Newtonsoft.Json;
using NwGeoExporter.NwEx;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.Models
{
public class Mesh
{
/// <summary>
/// 顶点数组-序列化数据
/// </summary>
public double[] vertices { get => VerticeList.SelectMany(x => new List<double> { x.X.Feet2Mm(), x.Y.Feet2Mm(), x.Z.Feet2Mm() }).ToArray(); }
/// <summary>
/// 顶点索引-序列化数据
/// </summary>
public int[] indices { get => IndiceList.ToArray(); }
/// <summary>
/// 顶点法向-序列化数据
/// </summary>
public double[] normals { get => NormalList.SelectMany(x => new List<double> { x.X, x.Y, x.Z }).ToArray(); }
/// <summary>
/// 顶点集合
/// </summary>
[JsonIgnore]
public List<PointM> VerticeList { get; set; }
/// <summary>
/// 顶点法线
/// </summary>
[JsonIgnore]
public List<VectorM> NormalList { get; set; }
/// <summary>
/// 顶点索引
/// </summary>
[JsonIgnore]
public List<int> IndiceList { get; set; }
/// <summary>
/// 材质索引
/// </summary>
public int material { get; set; }
public Mesh(int materialIndex)
{
VerticeList = new List<PointM>();
NormalList = new List<VectorM>();
IndiceList = new List<int>();
material = materialIndex;
}
public Mesh(IEnumerable<Triangle> triangles, int materialIndex) : this(materialIndex)
{
this.AddTriangles(triangles);
}
public Mesh(Triangle triangle, int materialIndex) : this(materialIndex)
{
this.AddTriangle(triangle);
}
public void AddTriangle(Triangle triangle)
{
for (int i = 0; i < triangle.Vertices.Length; i++)
{
bool isHandle = false;
//相同的顶点位置的索引
List<int> indexList = VerticeList.FindIndexs(x => x == triangle.Vertices[i]);
//当前三角面片顶点法向
VectorM currentVector = triangle.Normals[i];
//最后一次合并的索引
int lastMergeIndex = 0;
while (indexList.Count != 0)
{
//判断索引内是否需要合并的顶点
var index = indexList.FindIndex(x => NormalList[x].AngelTo(currentVector).ToAngle() - 90 > 0.1);
if (index == -1)
{
break;
}
else if (!isHandle)//第一次
{
NormalList[indexList[index]] = (currentVector + NormalList[indexList[index]]).Normalize();
currentVector = NormalList[indexList[index]];
lastMergeIndex = indexList[index];
indexList.RemoveAt(index);
isHandle = true;
}
else//原来顶点位置一致的与合并后的顶点进行比较
{
int removeIndex = Math.Max(lastMergeIndex, indexList[index]);
lastMergeIndex = Math.Min(lastMergeIndex, indexList[index]);
//重置索引
for (int k = 0; k < IndiceList.Count; k++)
{
if (IndiceList[k] > removeIndex)
{
IndiceList[k]--;
}
else if (IndiceList[k] == removeIndex)
{
IndiceList[k] = lastMergeIndex;
}
}
//删除不需要的顶点和法向
NormalList.RemoveAt(removeIndex);
VerticeList.RemoveAt(removeIndex);
}
}
if (!isHandle)
{
//添加顶点以及顶点法向以及对应的索引
VerticeList.Add(triangle.Vertices[i]);
NormalList.Add(triangle.Normals[i]);
IndiceList.Add(VerticeList.Count - 1);
}else
{
IndiceList.Add(lastMergeIndex);
}
}
}
public void AddTriangles(IEnumerable<Triangle> triangles)
{
foreach (var triangle in triangles)
{
this.AddTriangle(triangle);
}
}
}
}