Реброзависимые атрибуты
Предположим, мы хотим получить полигональный объект путём линеаризации параметрической оболочки и сохранить в вершинах 2D параметры на соответствующих гранях. Каждой грани будет соответствовать регион в сегментации. Но нумерация вершин в полигональном объекте сквозная, единая на всю сетку. И для вершин сетки, которые лежат на рёбрах и в вершинах сегментации, получается неоднозначная ситуация. Если такую вершину рассматривать по отношению к одной грани – ей должен соответствовать некий 2D параметр, а по отношению к другой – другой параметр. Таким образом, становится невозможным описывать 2D параметры простым атрибутом, ставящим в соответствие каждой вершине один параметр. То же самое относится к таким величинам, как нормали и кривизны.
Для поддержки таких ситуаций предусмотрены реброзависимые атрибуты – наследники базового класса MbHalfedgeAttrEdgeDependentVertexBase. Таких атрибутов три:
MbHalfedgeAttrParamByEdge;
MbHalfedgeAttrNormalsVertex;
MbHalfedgeAttrCurvaturesVertex.
Устроены они следующим образом (на примере нормалей). Нормали лежат отдельным массивом, и их количество и нумерация в этом массиве никак не связаны с вершинами сетки. Каждому ребру сетки ставится в соответствие индекс в массиве нормалей. Если это внутренняя для региона вершина, то все рёбра в её веере будут ссылаться на одну и ту же нормаль. Если эта вершина лежит на ребре сегментации или в вершине сегментации, то разным рёбрам веера соответствуют разные нормали.
Рассмотрим подробнее пример простой сетки из четырёх треугольников, показанной на рис. 1. Нормаль в вершине будем рассчитывать усреднением нормалей треугольников, входящих в её веер. Рассмотрим два случая:
первый – когда вся сетка образует одно целое (см. рисунок c)),
второй – когда она сегментирована на два плоских региона (см. рисунок a)).
Направление нормалей показано красными отрезками. В веере ближайшей угловой вершины есть три рёбра, исходящих из неё. Справа все они ссылаются на одну и ту же нормаль. Слева два красных рёбра (средний рисунок) ссылаются на нормаль N1, а одно зелёное – на нормаль N2.
Рис. 1
Таким образом, при наличии нормалей визуализация сегментированной и несегментированной сетки существенно отличается, как показано на рис. 2:
Рис. 2
Не следует интерпретировать метод атрибута нормалей
const MbVector3D & GetNormal( size_t iNm ) const;
как метод доступа к нормали вершины и использовать в качестве аргумента индекс вершины. Доступ к нормалям вершины должен быть организован через рёбра, которые из неё исходят, с помощью метода
const MbVector3D & GetNormalEdge( size_t iEd ) const;
Все реброзависимые атрибуты не предполагаются к созданию пользователем. Для их создания нужно вызывать функции ядра для расчёта этих величин. В этих функциях будет задана структура атрибутов, соответствующая текущей сегментации. При любых изменениях в топологии сегментации (объединение регионов, разбивка рёбрами сетки или фасетами и т.д.) структура имеющихся реброзависимых атрибутов будет также изменена согласно новой сегментации.