Find unique vertices from a 'triangle-soup'
我正在两个库(Opencascade和DWF Toolkit)的顶部构建一个CAD文件转换器。
但是,我的问题与平台无关:
鉴于:
我已经生成了一个网格,作为通过我的应用程序构建的模型的一系列三角形面的列表。每个三角形是通过三个顶点定义的,三个顶点由三个浮点数(x,y和z坐标)组成。由于三角形形成网格,因此大多数顶点由一个以上的三角形共享。
目标:
我需要找到唯一顶点的列表,并生成一个由该列表中三个索引的元组组成的面数组。
我想做的是这样的:
1 2 3 4 5 6 7 8 9 10 11 | //step 1: build a list of unique vertices for each triangle for each vertex in triangle if not vertex in listOfVertices Add vertex to listOfVertices //step 2: build a list of faces for each triangle for each vertex in triangle Get Vertex Index From listOfvertices AddToMap(vertex Index, triangle) |
虽然我确实有一个执行此操作的实现,但是step1(唯一顶点列表的生成)的速度确实慢于O(n!),因为将每个顶点与列表中已经存在的所有顶点进行了比较。我以为"嘿,让我们使用std :: map构建我的顶点组件的哈希图,应该加快速度!",却发现从三个浮点值生成唯一键并不是一件容易的事。
在这里,stackoverflow的专家开始发挥作用:我需要某种可在3个浮点数上使用的哈希函数,或任何其他从3d顶点位置生成唯一值的函数。
转储数组中的所有顶点,然后执行
我能想到的唯一警告是,您的
1 | distance(vertex1, vertex2) < threshold |
但这似乎还可以。
三种解决方案。当然还有其他
在情况2和3中,如果要指定一些公差,则需要搜索树或网格的多个部分。在BSP情况下,这意味着检查您是否在分隔平面的公差范围内,如果是,则递归到两个半部。在网格情况下,这意味着检查所有在公差范围内的相邻单元。两者都不是很难,但是这意味着使用"现成的"解决方案将更加困难。
获取哈希的常见想法是将浮点数的每个位模式与一个质数相乘,然后将它们加在一起。像这样:
1 2 3 4 5 6 7 8 | unsigned int hash_point(float x, float y, float z) { unsigned int* px = (unsigned int*)&x; unsigned int* py = (unsigned int*)&y; unsigned int* pz = (unsigned int*)&z; return (*px)*PRIME1 + (*py)*PRIME2 + (*pz)*PRIME3; } |
您应注意,此处的sizeof(unsigned int)等于sizeof(float)。这里的示例仅用于说明主要思想,您应该根据需要对其进行调整。