.. role:: blue :class: blue Реброзависимые атрибуты ======================= .. _Edge-Dependent_Attributes: .. версия ядра: 118027 Предположим, мы хотим получить полигональный объект путём линеаризации параметрической оболочки и сохранить в вершинах 2D параметры на соответствующих гранях. Каждой грани будет соответствовать регион в сегментации. Но нумерация вершин в полигональном объекте сквозная, единая на всю сетку. И для вершин сетки, которые лежат на рёбрах и в вершинах сегментации, получается неоднозначная ситуация. Если такую вершину рассматривать по отношению к одной грани – ей должен соответствовать некий 2D параметр, а по отношению к другой – другой параметр. Таким образом, становится невозможным описывать 2D параметры простым атрибутом, ставящим в соответствие каждой вершине один параметр. То же самое относится к таким величинам, как нормали и кривизны. Для поддержки таких ситуаций предусмотрены реброзависимые атрибуты – наследники базового класса :blue:`MbHalfedgeAttrEdgeDependentVertexBase`. Таких атрибутов три: - :blue:`MbHalfedgeAttrParamByEdge`; - :blue:`MbHalfedgeAttrNormalsVertex`; - :blue:`MbHalfedgeAttrCurvaturesVertex`. Устроены они следующим образом (на примере нормалей). Нормали лежат отдельным массивом, и их количество и нумерация в этом массиве никак не связаны с вершинами сетки. Каждому ребру сетки ставится в соответствие индекс в массиве нормалей. Если это внутренняя для региона вершина, то все рёбра в её веере будут ссылаться на одну и ту же нормаль. Если эта вершина лежит на ребре сегментации или в вершине сегментации, то разным рёбрам веера соответствуют разные нормали. Рассмотрим подробнее пример простой сетки из четырёх треугольников, показанной на рис. 1. Нормаль в вершине будем рассчитывать усреднением нормалей треугольников, входящих в её веер. Рассмотрим два случая: - первый – когда вся сетка образует одно целое (см. рисунок c)), - второй – когда она сегментирована на два плоских региона (см. рисунок a)). Направление нормалей показано красными отрезками. В веере ближайшей угловой вершины есть три рёбра, исходящих из неё. Справа все они ссылаются на одну и ту же нормаль. Слева два красных рёбра (средний рисунок) ссылаются на нормаль N1, а одно зелёное – на нормаль N2. .. figure:: ../../pictures/P.2.5.1.png :width: 21cm :align: center Рис. 1 Таким образом, при наличии нормалей визуализация сегментированной и несегментированной сетки существенно отличается, как показано на рис. 2: .. figure:: ../../pictures/P.2.5.2.png :width: 18cm :align: center Рис. 2 Не следует интерпретировать метод атрибута нормалей .. code-block:: cpp const MbVector3D & GetNormal( size_t iNm ) const; как метод доступа к нормали вершины и использовать в качестве аргумента индекс вершины. Доступ к нормалям вершины должен быть организован через рёбра, которые из неё исходят, с помощью метода .. code-block:: cpp const MbVector3D & GetNormalEdge( size_t iEd ) const; Все реброзависимые атрибуты не предполагаются к созданию пользователем. Для их создания нужно вызывать функции ядра для расчёта этих величин. В этих функциях будет задана структура атрибутов, соответствующая текущей сегментации. При любых изменениях в топологии сегментации (объединение регионов, разбивка рёбрами сетки или фасетами и т.д.) структура имеющихся реброзависимых атрибутов будет также изменена согласно новой сегментации.