Да.
"Сетка" - это просто набор полигонов (чаще всего треугольников) и их локальное соединение.На самом деле нет никакого способа узнать, где находятся границы (или даже сколько, или если таковые имеются) без их явного поиска.
Итерировать себя довольно просто.Однако вам необходимо принять во внимание, что, вероятно, существует несколько границ (например, дыр).Поэтому было бы разумно определить все границы и затем выбрать ту, которая вас интересует.
typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
typedef std::shared_ptr<MeshUtils::Mesh> MeshPtr;
typedef OpenMesh::HalfedgeHandle HEdgeHandle;
std::vector<HEdgeHandle> EnumerateBoundryCycles(MeshPtr mesh)
{
vector<HEdgeHandle> cycles_all;
size_t maxItr(mesh->n_halfedges());
mesh->request_halfedge_status();
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
mesh->status(he_itr).set_tagged(false);
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
{
if (mesh->status(he_itr).tagged())
continue;
mesh->status(he_itr).set_tagged(true);
if (false == mesh->is_boundary(he_itr))
continue;
// boundry found
cycles_all.push_back(*he_itr);
size_t counter = 1;
auto next_he = mesh->next_halfedge_handle(he_itr);
while ( (next_he != he_itr) && counter < maxItr)
{
assert(mesh->is_boundary(next_he));
assert(false == mesh->status(next_he).tagged());
mesh->status(next_he).set_tagged(true);
next_he = mesh->next_halfedge_handle(next_he);
counter++;
}
std::cout << "[EnumerateBoundryCycles]: Found cycle of length " << counter << std::endl;
if (counter >= maxItr)
{
std::cout << "WRN [EnumerateBoundryCycles]: Failed to close boundry loop." << std::endl;
assert(false);
}
}
mesh->release_halfedge_status();
return cycles_all;
}