Сеточное упрощение сетчатой ​​структуры

Я работаю над приложением для 3D-строительства. Строительство выполняется на трехмерной сетке (например, кубика Рубика), и каждая ячейка сетки представляет собой сплошной куб или наклон в 45 градусов. Для иллюстрации вот изображение куба со скошенной кромкой, которое я снял с изображений Google:

введите описание изображения здесь

Не обращайте внимания на изображение справа, фокус - тот, который находится слева. В настоящее время, на этапе строительства, я рисую каждую грань каждой ячейки отдельно. Однако, когда дело доходит до экспорта, я бы хотел его упростить. Итак, в приведенном выше кубе я бы хотел, чтобы грани вверх-вниз-влево-вправо-назад-передняя часть состояли из одного четырехугольника каждая (два треугольника), а края были бы уменьшены с двух четырехугольников до отдельных четырехугольников.

В последнее время я пытался сделать следующее:

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

Я явно слишком много усложняю (по крайней мере, я на это надеюсь). Если у меня есть список вершин, нормалей и индексов (в настоящее время с большим количеством повторяющихся вершин), есть ли какой-нибудь аккуратный способ упростить? Ограничения заключаются в том, что индексы не могут быть разделены между гранями (потому что мне нужны нормали, указывающие в разных направлениях), но в остальном я не возражаю, если это не самое быстрое или оптимальное решение, я бы предпочел, чтобы его было легко реализовать и поддерживать.

РЕДАКТИРОВАТЬ: Чтобы еще больше уточнить, я уже выполнил удаление скрытого лица, это не проблема. А во-вторых, очень важно, чтобы не было ухудшения качества, только упрощение самих граней (мне нужно сохранить острые грани).


person Fault    schedule 27.01.2014    source источник
comment
вы должны сначала сосредоточиться на удалении скрытых лиц   -  person ratchet freak    schedule 27.01.2014
comment
Вы читали этот документ? Ему 10 лет, но он все еще очень полезен. Также может помочь платформа OpenMesh.   -  person Roger Rowland    schedule 27.01.2014
comment
Ratchet - закончил с удалением скрытых граней, у меня просто нет общих вершин между гранями на данный момент. @Roger - Бумага выглядит великолепно! Буду изучать это. Что касается OpenMesh, я его рассмотрю. Я имел некоторый успех, попробовав инструмент прореживания Blender, хотя он потребовал изрядной ручной настройки, чтобы упростить его, не съедая какие-либо важные вершины. Многие методы слишком упрощаются без разбора, чтобы их можно было использовать.   -  person Fault    schedule 27.01.2014


Ответы (3)


Спасибо Роджеру Роуленду за отличные советы! Если кто-то еще наткнется на этот вопрос, вот краткое изложение того, что я сделал:

Первое, что нужно сделать: убедитесь, что сетка, которую вы пытаетесь упростить, - это многослойная сетка! Это требование для обхода половинчатых структур данных. Один случай, когда у меня возникли проблемы с этим, было наложение четырехугольников и треугольников; Изначально я решил просто оставить четырехугольники целыми, а не разбивать их на треугольники, потому что это было проще, но это привело к краям, которые сломали половинную сетку.

После того, как сетка станет многообразной, создайте сетку с половинным краем из вершин и граней.

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

Сначала я сделал это с помощью собственной реализации, но начал сталкиваться с неприятными ошибками и поэтому решил использовать вместо этого OpenMesh (с ним очень легко начать).

Есть еще одна проблема, которую мне еще предстоит решить: если два куба соприкасаются по диагонали друг от друга, в результате получается ребро с четырьмя соединенными с ним гранями: сложное ребро! Я подозреваю, что было бы тривиально перебирать ребра, проверяя количество соединенных граней, а затем разрешать путем дублирования соответствующих вершин. Но с учетом сказанного, это не то, на что я собираюсь тратить время, если только это не станет критической проблемой позже.

person Fault    schedule 05.02.2014

Даю теоретический ответ.

Для рисунка слева найдите все «треугольники с общими краями» с одинаковой нормалью (одинаковыми координатами x, y, z) (сделайте его единичной нормалью из-за отсутствия влияния направления положительного масштабирования векторов). Объедините их. Затем триангулируйте его с максимальным соотношением сторон, и вы получите желаемое решение.

Я предлагаю еще один простой и возможный способ упрощения сетки. Возьмите НОРМАЛЬНЫЕ и разделите на величину (корень из суммы квадратов координат), что дает единичный вектор нормали. Возьмите смежные треугольники и поместите между ними ТОЧЕЧНЫЙ ПРОДУКТ (умножьте координаты x, y, z каждый и сложите). Он дает значение COSINE угла между этими нормалями или треугольниками. Возьмите диапазон (например, 0,99–1) и рассмотрите все соседние треугольники в этом диапазоне относительно исходного треугольника, объедините их и выполните повторную триангуляцию. Мы определенно можем игнорировать некоторые треугольники в странных направлениях с меньшими областями.

Есть также другое предложение по более простому уменьшению сетки, как на левой фигуре или фигурах зданий. Определите заранее определенное количество граней (здесь 6 + 8 = 14), что означает значение нормалей, и классифицируйте все грани в соответствии с направлением, близким к ним (скалярным произведением), а затем объедините и ретриангулируйте.

person Jerin Vincent    schedule 24.10.2018

Google "упрощение сетки". Вы обнаружите, что эта проблема огромна и тщательно исследована. Взгляните на эти вводные ресурсы: ссылка ( с. 11 начинается самое интересное) и ссылка. У CGAL также есть хорошее обсуждение: ссылка.

Ознакомившись с проблемами, вы будете принимать некоторые решения по применению упрощения к вашей проблеме. Насколько быстрым должно быть упрощение? Насколько важна точность? (Итеративная кластеризация вершин - это быстрый и грязный подход, но ее результаты могут быть сколь угодно некрасивыми.) Можете ли вы положиться на стороннюю библиотеку? (например, CGAL? GTS больше не активен, но есть и другие).

person Throwback1986    schedule 27.01.2014