Для взаимодействия с модификатором Bevel, создающим фаску на заданных ребрах, каждому из выбранных ребер должен быть задан определенный числовой вес в пределах от 0.0 до 1.0. В ручном режиме вес для фаски задается в N-панели на вкладке Item – Edges Data – Mean Bevel Weight. Так же этот вес можно считывать и задавать через Blender Python API.
Для примера добавим в сцену “Сюзанну”, перейдем в режим редактирования, выделим несколько ребер и зададим им какое-то значение Mean Bevel Weight.
Значения этих весов для ребер хранятся в атрибуте меша с названием bevel_weight_edge.
В тот момент, когда мы задаем веса через панель UI, Blender автоматически создает этот атрибут и заносит в него задаваемые нами значения.
Для того чтобы считать заданные значения весов с ребер, нужно сначала “просчитать” (evaluate) меш – при помощи депсграфа получить итоговую копию данных меша с применением всех модификаторов, нод геометрии и всех остальных динамических изменений.
Для начала переключим меш в объектный режим.
1 2 |
obj = bpy.data.objects['Suzanne'] bpy.ops.object.mode_set(mode='OBJECT') |
При помощи депсграфа получим просчитанную копию данных меша.
1 |
obj_data = obj.evaluated_get(bpy.context.evaluated_depsgraph_get()).data |
Теперь мы можем обращаться к его атрибутам, в частности к нужному нам атрибуту bevel_weight_edge.
1 2 3 |
attr = obj_data.attributes['bevel_weight_edge'] # <bpy_struct, FloatAttribute("bevel_weight_edge") at 0x000001F56976F408> |
Пройдем по всем ребрам меша и выведем те из них, для которых в атрибуте bevel_weight_edge установлены значения больше 0.0.
1 2 3 4 5 6 7 |
for _index, edge in enumerate(obj_data.edges): if attr.data[_index].value > 0.0: print(edge, _index, attr.data[_index].value) # <bpy_struct, MeshEdge at 0x000001F5695CAD68> 420 1.0 # <bpy_struct, MeshEdge at 0x000001F5695CAD70> 421 1.0 # ... |
Это и есть отмеченные в Mean Bevel Weight ребра. Также мы вывели на печать и сами значения атрибута.
Через Python API мы можем не только получать, но и самостоятельно назначать Bevel Weight на нужные ребра.
Добавим в сцену еще одну “Сюзанну” и выделим несколько ребер на нем.
Если мы сейчас попробуем получить значения атрибута bevel_weight_edge, Blender выдаст ошибку об отсутствии этого атрибута на данном меше.
KeyError: ‘bpy_prop_collection[key]: key “bevel_weight_edge” not found’
1 2 3 4 5 6 |
obj1 = bpy.data.objects['Suzanne.001'] obj1_data = obj1.evaluated_get(bpy.context.evaluated_depsgraph_get()).data attr = obj1_data.attributes['bevel_weight_edge'] # KeyError: 'bpy_prop_collection[key]: key "bevel_weight_edge" not found' |
Так происходит потому что мы не назначали вес ребрам через UI и, соответственно, Blender не создавал этот атрибут.
Создадим его сами.
1 2 3 4 5 6 |
if 'bevel_weight_edge' not in obj1_data.attributes: obj1.data.attributes.new( name='bevel_weight_edge', type='FLOAT', domain='EDGE' ) |
Обратите внимание, что хотя мы и проверяем наличие атрибута на “просчитанном” меше, создаем атрибут мы на оригинальном меше.
В параметрах функции мы передаем имя атрибута, его тип FLOAT – числа с плавающей точкой и домен – для какой области меша создается атрибут, в нашем случае – для ребер.
Теперь мы точно так же можем пройти по всем ребрам меша и если ребро выделено – назначить этому ребру вес для фаски.
1 2 3 |
for _index, edge in enumerate(obj1.data.edges): if edge.select: obj1.data.attributes['bevel_weight_edge'].data[_index].value = 1.0 |
Таким образом мы задали нужный Bevel Weight для выделенных ребер меша.