我已经实现了以下代码来搜索和查找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模型中找到裁剪部分的其他更简单的算法?或者上面问题的任何解决方案?
答案 0 :(得分:0)
我使用stl(St. Lib。)的类地图找到答案。因此,我可以将模型的所有基础保存为矢量o坐标,然后将其作为地图的单个“关键点”,并将每个基础上的顶点作为值与关键字一起保存:
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();
}
就像我可以找到所有边缘基础而不必为每个基础检查这个属性(边缘基础)。