143 lines
4.8 KiB
C#
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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|