OpenMesh: получить дескриптор граничного полжеджа - PullRequest
0 голосов
/ 22 ноября 2018

У меня довольно простой вопрос по библиотеке C ++ OpenMesh .Удивительно, но я нигде не нашел ответа на этот вопрос.

Для данной сетки я хотел бы выполнить итерацию вдоль границы сетки.Из документации я знаю:

Вы можете выполнять итерации по границам, используя next_halfedge_handle ().Если вы находитесь на границе, то следующий полжедек гарантированно будет также пограничным полжеджем.

Пока все ясно.Но как мне получить начальный граничный полжедец, чтобы я мог использовать next_halfedge_handle() с этого момента?Неужели мне действительно нужно пройтись по всем полочкам, чтобы найти одно существо на границе?

Большое спасибо за вашу помощь.

1 Ответ

0 голосов
/ 24 ноября 2018

Да.

"Сетка" - это просто набор полигонов (чаще всего треугольников) и их локальное соединение.На самом деле нет никакого способа узнать, где находятся границы (или даже сколько, или если таковые имеются) без их явного поиска.

Итерировать себя довольно просто.Однако вам необходимо принять во внимание, что, вероятно, существует несколько границ (например, дыр).Поэтому было бы разумно определить все границы и затем выбрать ту, которая вас интересует.

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;
}
...