【问题标题】:Seperate list / mesh into sub-lists / sub-meshes将列表/网格分成子列表/子网格
【发布时间】:2015-02-03 17:56:58
【问题描述】:

编辑:想知道我有什么类型的网格:

想象一下顶部有四个旋钮的乐高积木。我读了一个包含整块砖表面的 STL 文件。在用唯一坐标识别所有节点(并将它们的下一个邻居保存在列表中)之后,我切掉了大部分砖块,因此只剩下四个旋钮。对我来说不幸的是,这四个旋钮仍然在一个大列表中(一个用于节点,一个用于下一个邻居)。如果我指定一个我知道属于该旋钮的节点,我希望以最快的方式获取一个旋钮的所有节点。

我有一个(相对)大的List<cNode> nodes 在哪里

class cNode
{
    int nodeNumber;
    cVector vector;
}

还有一个更大的(约 14e6 个条目)List<cNodeCoincidence> coincidences where

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&lt;cNode&gt;(firstNodeIKnow), globalResultListForSubmesh);调用,从而将递归结果写入更全局的列表。

此过程有效(使用小网格进行测试),但速度非常慢(在我中止该过程之前超过 15 小时)。

有没有什么方法可以更快更优雅地分离网格?

我找到了this SO post 并查看了this lecture,似乎这(尤其是 WQUPC)可能是我需要的,但我不明白它到底有什么帮助,因为他们只有一个节点列表,而我还有一个巧合列表,如果不使用会很遗憾,真的(?)。

数据库可以提供帮助吗(因为索引)?

【问题讨论】:

    标签: c# performance algorithm mesh


    【解决方案1】:

    您需要能够识别边缘。这是 2 个顶点之间的单个连接(没有找到更多其他连接)。我假设所有三角形都有所有顶点,因此它们是重复的。这当然取决于您的网格的尺寸,但它不应该花费这么多时间。

    您需要定义字典,这将泵送您的应用程序的内存,但也会在保证 O(1) 访问权限的情况下显着提高速度。

    简而言之:

    1) 加载数据

    2) 扫描它并构造适当的数据结构 如果您观察到任何 CAD 建模软件,在加载网格时会花费更多时间,原因相同:他们需要扫描加载的数据并构建适当的数据结构,以便能够尽快处理该数据。

    3) 使用这些数据结构尽可能快地获取您需要的信息。

    所以要明智地选择数据结构和键,以满足您的应用程序的要求。

    【讨论】:

    • 谢谢,但这并没有多大帮助。我的coincidences 列表实际上是一个边列表,其中每条边都出现一次且仅出现一次。我宁愿寻找一种方法来尽可能快地获取我的信息,而不是获取我必须获取信息的信息......
    • @lhiapgpeonk: 那么openedge 和顶点之间有关系吗?
    • 什么是opengge? coincidences 中的每个条目都由两个相互连接的顶点组成,即位于同一条边上。
    • @lhiapgpeonk:所以openedge 是在连接顶点集合中没有其他相同的2个顶点的事实。如果只有一对,那就是“开边”。
    • 我用三角形构建了coincidences,所以对于每个三角形,我指定了三个由两个顶点组成的边。我两个三角形共享一条边,它们也共享形成该边的两个顶点。由于该边缘将在coincidences 中出现两次,因此我将其删除,直到只剩下一个边缘。通过始终将 node1 定义为具有较小数字的节点的一致性,我捕获了所有双边。
    猜你喜欢
    • 2017-05-24
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多