Нахождение контуров граничных кромок в сетке треугольников с половинными гранями

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

Vertex { vec3 position, int edge /* any half edge leaving the vertex */}
HalfEdge {int vertex, int pair}
Triangle {int vertex[3], int normal[3]}
BoundaryEdge {int vertex, int pair, int next, int prev}

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

Если бы все петли были простыми, это было бы легко; однако сетки, с которыми я работаю, могут иметь граничные «стыки», то есть несколько граничных петель, которые имеют общую вершину. Это делает так, что есть точки в создании граничных циклов, где алгоритм должен решить, какое из нескольких возможных ребер является правильным следующим ребром в цикле. Если выбрано неправильное ребро, это может сделать невозможным итерацию по всем ребрам, инцидентным вершине.

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

Что мне было интересно, а) действительно ли мое решение будет работать, и б) есть ли другое более широко известное / используемое решение для поиска этих краевых петель, которое я еще не смог найти?


person Catlin    schedule 16.05.2015    source источник


Ответы (1)


Встречал похожую проблему. В моем случае несколько областей (представленных в виде набора треугольников) пересекаются в вершине / вершинах, и они являются границами. Цель - найти границу каждого региона. Я обнаружил, что использование окрестностей с одним кольцом (то есть edge.pair.next) сложно и неэффективно.

Что я сделал, так это то, что для каждой области я подумал обо всех треугольниках и ищу граничные края. Всякий раз, когда я нахожу граничный край, я записываю start_vertex и end_vertex в хэш-карту (map [start_vertex] = end_vertex, map [end_vertex] = start_vertex). После того, как вы пройдете через все треугольники в этой области, вы начнете с граничной вершины и используете хэш-карту для построения границы.

Если на границе триангуляции есть дыра, описанный выше метод не сработает, поскольку триангуляция не является многообразием. Решение: 1. Если на исходной поверхности есть дыры, попробуйте использовать интерполяцию, чтобы заполнить дыры. 2. Если на исходной поверхности нет отверстий, но в результирующей триангуляции есть одна, то проблема вызвана плохим кодом, который генерирует триангуляцию. Таким образом, вы можете изменить алгоритм, который генерирует триангуляцию.

person iefgnoix    schedule 20.07.2015
comment
То, что вы делаете, похоже на то, что делал я, и до определенной степени работает. Проблема с этим методом заключается в том, что он имеет тенденцию разваливаться, когда у вас есть сетка с отверстиями или другими неприятными вещами, которые создают ситуацию, когда у вас есть несколько граничных ребер, входящих и выходящих из одной и той же вершины. Когда это происходит, если ваша сетка требует определенных свойств, которые зависят от структуры контура граничного контура, тогда возникает проблема, какое ребро является правильным ребром для конкретного граничного контура. Так что для простых случаев это работает, но для более сложных - не так просто. - person Catlin; 24.07.2015
comment
Вы абсолютно правы. Мой метод не будет работать для сетки с отверстиями, особенно для сетки с отверстиями на границе, и в этом случае код попадает в бесконечный цикл. Вот как можно обойтись: 1. Если на исходной поверхности есть дыры, попробуйте использовать интерполяцию, чтобы заполнить дыры. В моем случае это работает, поскольку в моем случае не требуется сохранять топологию. 2. Если на исходной поверхности нет отверстий, но в результирующей триангуляции есть одна, то проблема вызвана плохим кодом, который генерирует триангуляцию. Таким образом, вы можете изменить алгоритм, который генерирует триангуляцию. - person iefgnoix; 25.07.2015
comment
Когда на границе есть дыры, сетка не является многообразной. Сама по себе это сложная тема даже в академических кругах. - person iefgnoix; 25.07.2015