С версии 4.1 оператор сглаживания нормалей в Blender был полностью заменен на модификатор, реализованный на механизме Geometry Nodes. Это удобно для решения ряда проблем, однако если модификатор Auto Smooth располагается в стеке модификаторов не на последнем месте, до других модификаторов, изменяющих геометрию меша, это приводит к появлению артефактов. Чтобы быстро переместить модификатор в конец стека, можно использовать несложный скрипт.
Автор скрипта Алексей Маслов.
Добавим так же опционально возможность установить для всех модификаторов требуемое значение угла сглаживания. Для этого в начале скрипта определим переменную, в которую занесем значение нужного нам угла (18 градусов) или None, если значение угла в модификаторе изменять не нужно.
1 |
set_angle = 18 # in degrees, None to skip |
Пройдем по всем выделенным объектам сцены в цикле.
1 |
for obj in bpy.context.selected_objects: |
А для каждого объекта по списку его модификаторов. Цикл проходи по копии списка, которую мы создаем срезом [:], чтобы избежать возможного зацикливания.
1 |
for modifier in obj.modifiers[:]: |
Определим нужный нам модификатор (Auto Smooth) по типу, он относится к нодовому типу и части имени.
1 |
if modifier.type == 'NODES' and 'Smooth' in modifier.node_group.name: |
Если нужный модификатор присутствует на меше, для начала поменяем угол сглаживания (если мы его установили заранее).
1 2 |
if set_angle is not None: modifier["Input_1"] = math.radians(set_angle) |
Теперь нам нужно сместить модификатор в конец стека. Воспользуемся для этого оператором modifier_move_to_index, который помещает модификатор на место по числовому индексу.
Чтобы оператор сработал правильно, перед его вызовом нужно сделать текущий меш активным.
1 |
bpy.context.view_layer.objects.active = obj |
Вызовем оператор, указав в параметрах имя модификатора и выставив индекс на 1 меньший общего числа модификаторов в списке.
1 2 3 4 |
bpy.ops.object.modifier_move_to_index( modifier=modifier.name, index=len(obj.modifiers) - 1 ) |
Модификатор будет перемещен в конец стека.
Полный код скрипта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import math import bpy set_angle = 18 # in degrees, None to skip for obj in bpy.context.selected_objects: for modifier in obj.modifiers[:]: if modifier.type == 'NODES' and 'Smooth' in modifier.node_group.name: # set angle if set_angle is not None: modifier["Input_1"] = math.radians(set_angle) # move modifier to the bottom of the modifiers stack bpy.context.view_layer.objects.active = obj bpy.ops.object.modifier_move_to_index( modifier=modifier.name, index=len(obj.modifiers) - 1 ) |