【问题标题】:How to find the slicing area in STL-Model如何在 STL-Model 中找到切片区域
【发布时间】:2016-02-17 10:03:37
【问题描述】:

我已经实现了以下代码来搜索和查找 STL 模型横截面上的顶点。由于我使用的模型通常包含超过百万个节点(顶点),因此如果我真的搜索所有节点(顶点)并检查它们是否在横截面区域中,那将是无效的。因此,一旦找到第一个节点,我只需检查邻居节点以找到下一个边缘节点。并继续到达我找到的第一个节点。

我想列出模型裁剪部分的所有蓝色顶点:

void findCroppingPoints()
{
unsigned int i, f;
int iFirst, k, kOld, p, cnt= 0;
bool isEdge1, isEdge2, isEdge3;

for (i = 0; i < (m_FacetList.size()); i++)
{
    isEdge1 = isEdge2 = isEdge3 = false;

//check the three edges of the triange i to see if they are on the cross-section.
    isEdge1 = isEdgeVertex(i, 1); 
    isEdge2 = isEdgeVertex(i, 2);
    isEdge3 = isEdgeVertex(i, 3);

    if (isEdge1 || isEdge2 || isEdge3)
    {
        iFirst = i;
        saveFacet:
        if (cnt == 0)
            if (isEdge1 = true)
                p = 0;
            else if (isEdge2 = true)
                p = 1;
            else
                p = 2;
        m_EdgePointList.push_back(m_FacetList[i]->vertex[p]);
            cnt++;

        for (f = 0; f < m_FacetList.size(); f++)
        {
            isEdge1 = isEdge2 = isEdge3 = false;
            if (f != iFirst)
                for (k = 0; k < 3; k++)
                {
                    if (m_FacetList[i]->vertex[p] == m_FacetList[f]->vertex[k]) // Search for the triangle, whiche contains the p (the edge, which has found before)
                    {
                        switch (k) // check, which of the two connected edges on this point is on the cross-section
                        {
                        case 0:
                            if (i != f || kOld != 1)
                                if (isEdgeVertex(f, 1))
                                {
                                    isEdge1 = true;
                                    p = 1;
                                    kOld = k;
                                    i = f; // Spring to the new-found triangle
                                    goto saveFacet;
                                }
                            if (i != f || kOld != 2)
                                if (isEdgeVertex(f, 3))
                                {
                                    isEdge3 = true;
                                    p = 2;
                                    kOld = k;
                                    i = f; // Spring to the new-found triangle
                                    goto saveFacet;
                                }
                            break;
                        case 1:
                            if (i != f || kOld != 0)
                                if (isEdgeVertex(f, 1))
                                {
                                    isEdge1 = true;
                                    p = 0;
                                    kOld = k;
                                    i = f; // Spring to the new-found triangle
                                    goto saveFacet;
                                }
                            if (i != f || kOld != 2)
                                if (isEdgeVertex(f, 2))
                                {
                                    isEdge2 = true;
                                    p = 2;
                                    kOld = k;
                                    i = f; // Spring to the new-found triangle
                                    goto saveFacet;
                                }
                            break;
                        case 2:
                            if (i != f || kOld != 1)
                                if (isEdgeVertex(f, 2))
                                {
                                    isEdge2 = true;
                                    p = 1;
                                    kOld = k;
                                    i = f; // Spring to the new-found triangle
                                    goto saveFacet;
                                }
                            if (i != f || kOld != 0)
                                if (isEdgeVertex(f, 3))
                                {
                                    isEdge3 = true;
                                    p = 0;
                                    kOld = k;
                                    i = f; // Spring to the new-found triangle
                                    goto saveFacet;
                                }
                            break;
                        }
                    }
                }
        }
        break;
    }
}
}

这是我检查三角形的边是否代表横截面边的方法:

bool CSTLModel::isEdgeVertex(unsigned int FacetNum, int VertexNum)
{
bool isEdge;
unsigned int f1, f2, f3;
int k1, k2, p1, p2;

switch (VertexNum)
{
case 1:
    p1 = 0;
    p2 = 1;
    break;
case 2:
    p1 = 1;
    p2 = 2;
    break;
case 3:
    p1 = 2;
    p2 = 0;
    break;
}
for (f1 = 0 ; f1 < m_FacetList.size(); f1++)
    {
        if (f1 != FacetNum)
        {
            isEdge = true;
            for (k1 = 0; k1 < 3; k1++)
                if (m_FacetList[FacetNum]->vertex[p1] == m_FacetList[f1]->vertex[k1])
                    for (k2 = 0; k2 < 3; k2++)
                        if (m_FacetList[FacetNum]->vertex[p2] == m_FacetList[f1]->vertex[k2])
                        {
                            isEdge = false;
                            goto endLoop;
                        }
        }
    }
endLoop:
return isEdge;
}

但是如果模型上有多个裁剪部分,那将不起作用,我无法跳转到下一部分,而不必搜索所有节点。

您知道在 STL 模型中查找裁剪部分的其他更简单的算法吗?或者上述问题的任何解决方案?

【问题讨论】:

  • 这是一个 3D 模型。三角形在空间中。所以每个顶点都用空间中的x、y、z坐标来表示。
  • 首先你需要生成边界面列表。很明显,如果我们没有任何关于裁剪部分数量的信息,就没有办法避免检查所有面的这个属性。因此,您需要尽可能高效地进行这些检查,因为有很多面孔。之后,您将只检查此列表中的面的顶点。

标签: c++ cad


【解决方案1】:

我使用 stl (St. Lib.) 的类映射找到了答案。所以我可以将模型的所有 Bases 保存为向量 o 坐标,然后保存为地图的单个“键”,并将每个 Base 上的顶点作为与键相结合的值:

    findCroppingPoints()
{
    long int oldMapSize = 0;
    unsigned char p1, p2;
    std::map<std::vector<double>, Coordinate<double>> baseMap;
    std::vector<double> baseVector;
    for (int i = 0; i < m_FacetList.size(); ++i)
    {
        for (unsigned char j = 0; j < 6; ++j)
        {
            switch (j) 
            {
            case 0:
                p1 = 0;
                p2 = 1;
                break;
            case 1:
                p1 = 0;
                p2 = 2;
                break;
            case 2:
                p1 = 1;
                p2 = 0;
                break;
            case 3:
                p1 = 1;
                p2 = 2;
                break;
            case 4:
                p1 = 2;
                p2 = 0;
                break;
            case 5:
                p1 = 2;
                p2 = 1;
                break;
            default:
                throw ErrorObj("Unknown_flag.");
            }
            baseVector.push_back(m_FacetList[i]->vertex[p1].x());
            baseVector.push_back(m_FacetList[i]->vertex[p1].y());
            baseVector.push_back(m_FacetList[i]->vertex[p1].z());
            baseVector.push_back(m_FacetList[i]->vertex[p2].x());
            baseVector.push_back(m_FacetList[i]->vertex[p2].y());
            baseVector.push_back(m_FacetList[i]->vertex[p2].z());

只要地图的大小没有改变,就意味着最后一个键(向量)已经存在,因此没有边基

oldMapSize = baseMap.size();
                baseMap[baseVector] = m_FacetList[i]->vertex[p1];
                if (oldMapSize == baseMap.size())
                {
                    baseMap.erase(baseVector);
                }
                baseVector.clear();
            }
        }
        std::map<std::vector<double>, Coordinate<double>>::iterator it = baseMap.begin();
        while (it != baseMap.end())
        {
            m_EdgePointList.push_back(it->second);
            ++it;
        }
        baseMap.clear();
    }

就像这样我可以找到所有的边缘基础,而无需检查每个基础的这个属性(作为边缘基础)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 2014-12-04
    • 1970-01-01
    相关资源
    最近更新 更多