У меня довольно простой вопрос по библиотеке C ++ OpenMesh. Удивительно, но я нигде не нашел ответа на это.
Для данной сетки я хотел бы пройти по границе сетки. От документация Я знаю:
Вы можете перебирать границы, используя next_halfedge_handle (). Если вы находитесь на границе, то следующий полжедек также гарантированно будет полужестком.
Пока все ясно. Но как мне получить начальный граничный полжунж, чтобы я мог использовать next_halfedge_handle()
С тех пор? Должен ли я действительно перебирать все полжеджи, чтобы найти одно существо на границе?
Большое спасибо за вашу помощь.
Да.
«Сетка» — это просто набор многоугольников (чаще всего треугольников) и их местный подключение. На самом деле нет никакого способа узнать, где находятся границы (или даже сколько, или если таковые имеются) без явного их поиска.
Итерировать себя довольно просто. Однако вы должны принять во внимание, что, вероятно, существует несколько границ (например, дыр). Поэтому было бы разумно определить все границы, а затем выбрать ту, которая вас интересует.
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;
}
Других решений пока нет …