编辑:了解我的网格类型:
想象一下顶部带有四个旋钮的乐高积木。我读了一个包含整块砖表面的STL文件。在识别出具有唯一坐标的所有节点(并将其下一个邻居保存在列表中)之后,我切掉了大部分砖块,因此只剩下四个旋钮。不幸的是,这四个旋钮仍然在一个大的列表中(一个用于节点,一个用于下一个邻居)。如果我指定一个我知道属于该旋钮的节点,我想以最快的方式获取一个旋钮的所有节点。
我有一个(相对)大的List<cNode> nodes
class cNode
{
int nodeNumber;
cVector vector;
}
和更大的(约14e6条目)List<cNodeCoincidence> coincidences
其中
class cNodeCoincidence
{
cNode node1;
cNode node2;
}
我的节点代表3D中的点,我的巧合类似于以前由三角形组成的网格,从STL文件压缩。我知道一个事实(并且用户相应地做了他的输入),我的节点网格实际上是一个节点/重合列表中的4个单独的网格。我的目标是将每个子网格的节点提取到自己的节点列表。为了实现这一点,我从每个子网格的一个节点开始,我知道它是所述子网格的一部分。提示递归函数:
private void AssembleSubMesh(ReadOnlyCollection<cNode> in_nodesToRead, List<cNode> in_nodesAlreadyRead)
{
List<cNode> newNodesToRead = new List<cNode>();
List<cNodeCoincidence> foundCoincidences = coincidences.Where(x => (in_nodesToRead.Any(y => y == x.node1)) || in_nodesToRead.Any(z => z == x.node2)).ToList();
in_nodesAlreadyRead.AddRange(in_nodesToRead);
List<cNode> allRemainingNodes = new List<cNode>();
foreach (cNodeCoincidence nc in foundCoincidences)
{
allRemainingNodes.Add(nc.node1);
allRemainingNodes.Add(nc.node2);
}
allRemainingNodes = allRemainingNodes.Distinct().ToList();
allRemainingNodes.RemoveAll(x => in_nodesAlreadyRead.Contains(x));
if (allRemainingNodes.Count != 0)
AssembleSubMesh(new ReadOnlyCollection<cNode>(allRemainingNodes), in_nodesAlreadyRead);
}
由AssembleSubMesh(new ReadOnlyCollection<cNode>(firstNodeIKnow), globalResultListForSubmesh);
调用,从而将递归结果写入更全局的列表。
此程序有效(使用小网格测试),但速度很慢(在我中止过程之前超过15小时)。
有没有办法以更快,更优雅的方式分离网格?
我找到了this SO post并看了this lecture,似乎有可能这个(特别是WQUPC)是我需要的,但我不明白它到底是怎么回事可以提供帮助,因为他们只有一个节点列表,而且我还有巧合列表,这对于不使用非常遗憾,真的(?)。
数据库是否有帮助(因为索引)?
答案 0 :(得分:0)
您需要能够识别 edge 。这是2个顶点之间的单个连接(不再找到其他连接)。我假设所有三角形都有顶点,因此它们是重复的。这取决于您的网格的尺寸确定,但它不应该花费这么多时间。
您需要定义字典,这将填充您应用的内存,但也会通过保证O(1)访问来显着提高速度。
简而言之:
1)加载数据
2)扫描并构建适当的数据结构 如果您观察任何CAD建模软件,则在加载网格时需要花费更多时间,原因相同:它们需要扫描加载的数据并构建适当的数据结构,以便能够尽可能快地处理该数据。
3)使用这些数据结构尽可能快地获取您需要的信息。
因此,明智地选择数据结构和密钥,以满足 应用程序的要求。