基本上我使用MeshGeometry3D
从STL文件加载点,位置和法线。
STL文件格式重复点,所以我想在添加新读取点之前首先搜索MeshGeometry3D.Positions
重复。
Mesh.Positions.IndexOf(somePoint3D)
不起作用,因为它基于对象引用而不是Point3D
的X,Y,Z值进行比较。这就是为什么我要迭代整个Collection来手动查找重复项:
//triangle is a custom class containing three vertices of type Point3D
//for each 3 points read from STL the triangle object is reinitialized
vertex1DuplicateIndex = -1;
vertex2DuplicateIndex = -1;
vertex3DuplicateIndex = -1;
for (int q = tempMesh.Positions.Count - 1; q >= 0; q--)
{
if (vertex1DuplicateIndex != -1)
if (tempMesh.Positions[q] == triangle.Vertex1)
vertex1DuplicateIndex = q;
if (vertex2DuplicateIndex != -1)
if (tempMesh.Positions[q] == triangle.Vertex2)
vertex2DuplicateIndex = q;
if (vertex3DuplicateIndex != -1)
if (tempMesh.Positions[q] == triangle.Vertex3)
vertex3DuplicateIndex = q;
if (vertex1DuplicateIndex != -1 && vertex2DuplicateIndex != -1 && vertex3DuplicateIndex != -1)
break;
}
当找到重复项时,此代码实际上非常有效,但是当没有重复时,集合将完全迭代,对于具有超过一百万个位置的大网格来说非常慢。
搜索还有其他方法吗?
有没有办法强制Mesh.Positions.IndexOf(newPoint3D)
根据Mesh.Positions[index]==(somePoint3D)
之类的值进行比较,而不是现在正在进行的参考比较?
答案 0 :(得分:1)
我不知道内置的方法,但您可以使用哈希映射来缓存3D矢量的索引。 根据向量的哈希函数的质量,您将拥有一种''常量查找(没有碰撞是不可能的,但它应该比迭代每个新三角形点的所有顶点数据更快。)
答案 1 :(得分:0)
使用hakononakani的想法我使用HashSet
和Dictionary
的组合设法加快了速度。以下是我的代码的简化版本:
class CustomTriangle
{
private Vector3D normal;
private Point3D vertex1, vertex2, vertex3;
}
private void loadMesh()
{
CustomTriangle triangle;
MeshGeometry3D tempMesh = new MeshGeometry3D();
HashSet<string> meshPositionsHashSet = new HashSet<string>();
Dictionary<string, int> meshPositionsDict = new Dictionary<string, int>();
int vertex1DuplicateIndex, vertex2DuplicateIndex, vertex3DuplicateIndex;
int numberOfTriangles = GetNumberOfTriangles();
for (int i = 0, j = 0; i < numberOfTriangles; i++)
{
triangle = ReadTriangleDataFromSTLFile();
vertex1DuplicateIndex = -1;
if (meshPositionsHashSet.Add(triangle.Vertex1.ToString()))
{
tempMesh.Positions.Add(triangle.Vertex1);
meshPositionsDict.Add(triangle.Vertex1.ToString(), tempMesh.Positions.IndexOf(triangle.Vertex1));
tempMesh.Normals.Add(triangle.Normal);
tempMesh.TriangleIndices.Add(j++);
}
else
{
vertex1DuplicateIndex = meshPositionsDict[triangle.Vertex1.ToString()];
tempMesh.TriangleIndices.Add(vertex1DuplicateIndex);
tempMesh.Normals[vertex1DuplicateIndex] += triangle.Normal;
}
//Do the same for vertex2 and vertex3
}
}
最后tempMesh
只有唯一的点数。您所要做的就是将所有Normals
标准化,然后您就可以进行可视化了。
只有Dictionary
使用:
if (!meshPositionsDict.Keys.Contains(triangle.Vertex1.ToString()))
我只是喜欢使用HashSet
,因为使用它很有趣:)
在这两种情况下,最终结果是 ~60倍算法比以前更快!