Сегментация и сегментационные итераторы

Сегментация над полигональной сеткой также организована в виде Halfedge структуры. Для её представления используются следующие элементы, которые находятся в заголовочном файле halfedge_element.h. Каждый из сегментационных элементов может быть в активном и неактивном статусе.

Подрегион (MbSegmentationSubRegion) – связная группа фасетов.

Регион – группа из нескольких подрегионов, как правило, из одного. Отдельного класса, описывающего регион, нет.

Ребро сегментации – последовательность рёбер сетки, такая, что каждое следующее ребро исходит из вершины, в которую приходит предыдущее ребро. Ребро сегментации может быть замкнутым. Самопересечения рёбер не допускаются. Аналогично ребру сетки ребро сегментации имеет ссылки на следующее ребро сегментации, предыдущее ребро сегментации, ребро сегментации-близнеца и вершину, за счёт чего формируются циклы. Если ребро сегментации принадлежит открытой границе, ссылка на близнеца отсутствует. Сеточные рёбра, входящие в ребро сегментации и его близнеца, тоже являются близнецами (рис. 1):

../../../_images/P.2.3.1ru.png

Рис. 1

Вершина сегментации – соответствует вершине сетки, в которой сходятся несколько рёбер сегментации.

Цикл подрегиона (MbSegmentationLoop), состоящий из последовательности рёбер сегментации. Подрегион может иметь сколько угодно циклов или вообще ни одного, если он представляет из себя замкнутую группу фасетов. Имеет такой же смысл, как цикл грани в граничном представлении, с некоторыми отличиями. Как правило, на сетке нельзя разделить циклы на внешний и внутренние, поэтому все циклы равноправны. Также цикл может иметь «внутренние» рёбра.

Пример разделения сетки на четыре региона, каждый из которых состоит из одного подрегиона, показан на рис. 2:

../../../_images/P.2.3.2.png

Рис. 2

Пример для той же сетки, но теперь в сегментации два региона, один из которых состоит из одного подрегиона, а другой из трёх, показан на рис. 3:

../../../_images/P.2.3.3.png

Рис. 3

Пример подрегиона с двумя циклами показан на рис. 4. Зелёный цикл полностью состоит из внутренних рёбер, в красном внутренними являются рёбра 1, 2, 4–9.

../../../_images/P.2.3.4.png

Рис. 4

Для работы с топологией сегментации предназначены сегментационные итераторы, которые находятся в заголовочном файле halfedge_segm_iterators.h:

  • EdgeLoopIterator – итератор по рёбрам цикла подрегиона. В зависимости от флага bExcludeInnerEdges возвращает последовательность всех рёбер цикла либо только внешних.

  • EdgeEdgesIterator – итератор по сеточным рёбрам ребра сегментации. В зависимости от флага bReverse возвращает последовательность сеточных рёбер в прямом либо обратном порядке.

  • SubregionRegionIterator – итератор по подрегионам региона.

  • LoopSubregionIterator – итератор по циклам подрегиона.

Для итерации по вееру вершин сегментации нужно использовать итератор EdgeFanIterator, как показано в примере ниже.

Примеры использования сегментационных итераторов:

MbPolymesh polymesh;

const MbPolymeshTopo & topo = *polymesh->GetTopo();

const MbHalfedge & halfedge = topo.GetMeshTopo();

for( size_t r = 0; r < topo.RegionCount(); ++r ) {

    if( !topo.IsRegionActive( r ) )
        continue;

    for( SubregionRegionIterator itSub( topo, r ); !itSub.Done(); ++itSub ) {

        for( LoopSubregionIterator itLoop( topo, itSub.Subregion() ); !itLoop.Done(); ++itLoop ) {

            for( EdgeLoopIterator itEdge( topo, itLoop.Loop() ); !itEdge.Done(); ++itEdge ) {

                for( EdgeEdgesIterator it( topo, itEdge.Edge() ); !it.Done(); ++it ) {

                    const MbHalfedgeEdge & ed = halfedge.Edge( it.Edge() );
                    ...
                }
            }
        }
    }
},

for( EdgeFanIterator it( topo.GetSegmTopo(), iVxSegm, true ); !it.Done(); ++it ) {

    const MbHalfedgeEdge & edSegm = topo.GetSegmTopo().Edge( it.Edge() );
}