我正在使用HalfEdge数据结构来表示网格上面之间的连通性。
我正在导入一个外部模型,并且在导入过程中正在构建HalfEdge结构。但是,对于具有许多三角形的网格,构建过程会占用太多时间。
具体来说,似乎连接半边的过程最多。 我想获得一些有关如何改进算法的建议。
下面是我用来初始化数据结构的代码。第一个for循环使用顶点数据创建一个Face
,同时将组成console.log('start constructing DCEL', new Date().toTimeString());
// initialize Half-Edge data structure (DCEL)
const initialFaceColor = new THREE.Color(1, 1, 1);
const { position } = geometry.attributes;
const faces = [];
const edges = [];
let newFace;
console.log('start making faces', new Date().toTimeString());
for (let faceIndex = 0; faceIndex < (position.count / 3); faceIndex++) {
newFace = new Face().create(
new THREE.Vector3().fromBufferAttribute(position, faceIndex * 3 + 0),
new THREE.Vector3().fromBufferAttribute(position, faceIndex * 3 + 1),
new THREE.Vector3().fromBufferAttribute(position, faceIndex * 3 + 2),
faceIndex);
edges.push(newFace.edge);
edges.push(newFace.edge.next);
edges.push(newFace.edge.prev);
newFace.color = initialFaceColor;
faces.push(newFace);
}
console.log('end making faces', new Date().toTimeString());
console.log('start linking halfEdges', new Date().toTimeString());
/**
* Find and connect twin Half-Edges
*
* if two Half-Edges are twins:
* Edge A TAIL ----> HEAD
* = =
* Edge B HEAD <---- TAIL
*/
let currentEdge;
let nextEdge;
for (let j = 0; j < edges.length; j++) {
currentEdge = edges[j];
// this edge has a twin already; skip to next one
if (currentEdge.twin !== null) continue;
for (let k = j + 1; k < edges.length; k++) {
nextEdge = edges[k];
// this edge has a twin already; skip to next one
if (nextEdge.twin !== null) continue;
if (currentEdge.head().equals(nextEdge.tail())
&& currentEdge.tail().equals(nextEdge.head())) {
currentEdge.setTwin(nextEdge);
}
}
}
console.log('end linking halfEdges', new Date().toTimeString());
console.log('end constructing DCEL', new Date().toTimeString());
的HalfEdges推入一个单独的数组中,稍后再使用。
第二个for循环负责调查所有HalfEdges的数组,并找到匹配的对(即,彼此成对的两个)。
我注销了每个过程之前和之后的时间,并注意到第二个循环使一切变慢。
这是时间戳记
开始构建DCEL 14:55:22
开始做鬼脸14:55:22
做鬼脸14:55:22
/ *这是要花很长时间的地方。在具有13000个三角形的网格上,将近6秒* /
开始链接HalfEdges 14:55:22
结束链接HalfEdges 14:55:28
结束构建DCEL 14:55:28
这是实际代码
{{1}}
如何优化搜索双边缘的过程?
答案 0 :(得分:2)
我会尝试哈希并查找边缘,例如像这样:
function hash(p1, p2) {
return JSON.stringify(p1)+JSON.stringify(p2);
}
const lookup = {}
for (let j = 0; j < edges.length; j++) {
lookup[hash(edge.head(), edge.tail())] = edge;
}
for (let j = 0; j < edges.length; j++) {
const twin = lookup[hash(edge.tail(), edge.head())];
!edge.twin && twin && !twin.twin && edge.setTwin(twin);
}