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