Как обрезать треугольники в выходной сетке реконструкции поверхности Облака точек

#cgal

Вопрос:

У меня есть открытая поверхность, представленная облаком точек, которое я провел с помощью шагов, описанных в руководстве по обработке набора точек и реконструкции поверхности. Однако применение любого из 3 рассмотренных алгоритмов реконструкции приводит к созданию замкнутой сетки с крайними внешними полигонами, особенно вдоль «окружающего купола» атмосферы вокруг модели облака точек. См. Прикрепленные изображения внизу этого вопроса для визуального контекста.

Существует ли точный или канонически правильный метод в CGAL для обрезки как больших, так и малых треугольников, которые не пересекаются с исходным облаком точек? Я попытался выполнить итерацию по граням в выходной сетке и удалить грани, которые удовлетворяют одному из двух условий: (1) Любая длина данной грани больше среднего расстояния, вычисленного для облака исходных точек, и (2) Заданная площадь грани превышает некоторый порог. Любое условие фильтрации приводит к модели, которая не отображается в виде сетки в формате СЛОЯ, учитывая различные средства просмотра, которые я пробовал. Вот некоторый код, который я рассмотрел, но, по-видимому, не выполняет эту работу:

 for (face_descriptor faced : output_mesh.faces()) {
        //std::cout << faced << std::endl;
        std::vector<double> lengths;

        // Get edges from face descriptor
        //    - NOTE :> Assume three total half-edges because triangles.  Not guaranteed, tho.
        for (halfedge_descriptor hed : CGAL::halfedges_around_face( output_mesh.halfedge(faced), output_mesh )) {

            vertex_descriptor target_vertex = output_mesh.target(hed);
            Point_3amp; target_point = output_mesh.point(target_vertex);

            halfedge_descriptor hed_next = output_mesh.next(hed);
            vertex_descriptor target_next = output_mesh.target(hed_next);
            Point_3amp; target_point_next = output_mesh.point(target_next);

            double length = CGAL::sqrt(CGAL::squared_distance(target_point, target_point_next));
            lengths.push_back(length);
            simplex.push_back(target_point);
        }

        // if edge length greater than limit threshold based on average_spacing, 
        // mark for removal?
        for (double length : lengths) {
            if (length > average_spacing) {

                output_mesh.remove_face(faced);
                //CGAL::Euler::remove_face( output_mesh.halfedge(faced), output_mesh );

                std::cout << "Removed face " << faced << " with lengths: ";
                // List out the lengths found:
                for (double length : lengths) {
                    std::cout << length << ", ";
                }
                std::cout << std::endl;
                continue;
            }
        }
    }

    // clear faces marked as removed
    output_mesh.collect_garbage();
    //output_mesh.is_valid();
 

Заранее спасибо за ваши идеи! Это заставляло меня ходить по кругу в течение нескольких недель.

Исходное облако точек с оценочными нормалями

Результирующая Выходная Сетка

Комментарии:

1. Вы использовали наступающий фронт? Если да, то размер порога лица не помог?

2. @sloriot Так что да, я использовал и Пуассона, и Фронт продвижения, и оба результата привели к одному и тому же «воздушному шару». Я вернусь и проверю в выходные, чтобы еще раз проверить, существовало ли такое же поведение. Я использовал новый конвейер Point_Set_3 без именованных параметров, потому что они вызывали у меня головную боль. Попытается добавить пороговый размер и сообщить об этом.

Ответ №1:

Следуя комментарию @sloriot, использование предварительной реконструкции передней поверхности является правильным способом решения этой проблемы, в дополнение к этапам заполнения отверстий и обтекания.

Однако из-за смежного характера наступающего фронта все еще возникают некоторые посторонние аспекты. Решение, которое мы разработали, включает в себя проецирование различных точек на каждую грань; вычисление расстояния до плоскости грани (симплекса) и барицентрических координат каждой точки в качестве критериев фильтрации. Это позволяет удалять грани, которые не соответствуют каким-либо облакам точек. Рекомендуется сделать это до заполнения отверстий/обтекания или возможного применения других алгоритмов из набора обработки многоугольной сетки для выполнения некоторых дополнительных «исправлений» для нашего приложения.

Большое спасибо за помощь!