Соответствие полигонов и треугольников при триангуляции меша в Blender

Одним из методов аналитической оценки меша является оценка его триангулированной геометрии. Например, подобная оценка проводится при поиске полигонов, которые перекрываются, как в самом меше, так и в его UV-развертке. Для того чтобы вернуть результат, полученный после анализа триангулированного меша обратно в исходный меш, нужно знать точное соответствие между исходным полигоном и полученными из него треугольниками.

Сам по себе оператор bmesh.ops.triangulate(), при помощи которого проще всего триангулировать меш, предоставляет определенный инструмент для поиска такого соответствия, однако его стоит немного доработать.

Для примера из текущего активного меша создадим bmesh и приведем в соответствие индексы для его точек, ребер и полигонов. Так же сделаем его копию, она нам пригодится немного позднее.

Теперь мы можем триангулировать полученный bmesh.

Вся работа по триангуляции производится сразу в bmesh объекте, однако для дальнейших действий нам также нужен результат, возвращаемый функцией триангуляции.

Функция bmesh.ops.triangulate() возвращает словарь, состоящий в свою очередь из четырех словарей: “edges”, “faces”, “face_map” и “face_map_double”.

Из них нам наиболее полезен будет словарь “face_map”. Этот словарь имеет следующий формат: {треугольник: исходный полигон, треугольник: исходный полигон, …}.

Такой словарь дает нам возможность проводить соответствие треугольник-полигон со стороны полученного триангулированного меша, однако гораздо полезнее иметь возможность получать набор полученных треугольников отталкиваясь от исходного полигона.

Мы можем получить список вида ((треугольник, полигон), (треугольник, полигон), …) при помощи функции items().

Однако такой формат тоже не дает возможности быстро получить нужные данные.

Давайте инвертируем словарь “face_map”.

И теперь мы уже получаем что-то похожее на то что нам нужно – через функцию items() мы получаем список вида ((исходный полигон, [треугольник, треугольник]), …).

Однако здесь есть еще одна особенность – если в исходном меше изначально присутствовали треугольные полигоны, они, что логично, не были триангулированы, и не попали в итоговый список. Мы можем проверить это просто сравнив длины полученного списка, списка всех полигонов исходного меша и списка треугольных полигонов в исходном меше.

Как мы видим, общее количество полигонов – 500 у нас может складываться из количества полигонов в инвертированной face_map – 468, и количества треугольников в исходном полигоне – 32.

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

И сделаем такой же словарь для недостающих треугольников из исходного меша. Как раз для этого мы сохраняли отдельную копию нетриангулированного bmesh в начале.

Объединим оба словаря в один.

В итоге мы получили полный словарь с ключами – индексами исходных полигонов, и элементами – треугольниками после триангуляции.

Для того чтобы быстро получить треугольники, которые были созданы из полигона с индексом, например, 322, нам нужно просто обратиться по этому индексу к нашему финальному словарю:

Если нам требуется сохранить триангулирование, запишем результат из bmesh обратно в исходный меш и удалим теперь уже не нужный bmesh.

0 0 голоса
Article Rating
Подписаться
Уведомить о
guest

0 Комментарий
Новые
Старые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии