При разработке аддонов часто бывает необходимо предоставить пользователю возможность задавать ряд параметров, влияющих на общую работу аддона. Например, пользователь может указать постоянную директорию для загрузки/сохранения файлов или задать тот или иной режим работы аддона. Конечно, интерфейс для задания подобных параметров можно разместить и в рабочей панели аддона, но гораздо удобнее поместить его в отдельную панель свойств аддона, которая размещается под панелью инсталляции аддона в окне Preferences.
Основное преимущество определения таких глобальных свойств аддона в том, что они не сбрасываются при перезапуске Blender. Пользователю не нужно каждый раз производить настройку аддона, достаточно один раз установить нужные параметры, персонализировав аддон для удобной работы.
Создадим простейший аддон и добавим ему глобальный параметр, поместив его в панель свойств аддона:
Для начала создадим простейший аддон, который по нажатию на кнопку в N-панели 3D-окна будет создавать дефолтный куб.
Код аддона:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import bpy bl_info = { 'name': 'test', 'category': 'All', 'author': 'Korchiy', 'version': (0, 0, 1), 'blender': (2, 80, 0), 'location': '3D_Viewport window -> N-Panel > Test', 'description': 'Test' } class addCubeSample(bpy.types.Operator): bl_idname = 'mesh.add_cube_sample' bl_label = 'Add Cube' bl_options = {"REGISTER", "UNDO"} def execute(self, context): bpy.ops.mesh.primitive_cube_add() return {"FINISHED"} class addCubeSamplePanel(bpy.types.Panel): bl_idname = 'test.panel' bl_label = 'TEST' bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'TEST' def draw(self, context): self.layout.operator("mesh.add_cube_sample", icon='MESH_CUBE', text="Add Cube") def register(): bpy.utils.register_class(addCubeSample) bpy.utils.register_class(addCubeSamplePanel) def unregister(): bpy.utils.unregister_class(addCubeSamplePanel) bpy.utils.unregister_class(addCubeSample) if __name__ == '__main__': register() |
Здесь мы создали аддон с именем “test” для Blender версии 2.8.
В нем мы определяем класс-оператор с именем “addCubeSample”, который вызывается по идентификатору “mesh.add_cube_sample”.
В методе “execute” класса-оператора мы просто вызываем системный оператор “mesh.primitive_cube_add”, который и создает дефолтный куб.
Так же мы определили панель с именем “TEST” в окне 3D Viewport и разместили на ней кнопку вызова нашего оператора “mesh.add_cube_sample”, создав класс “addCubeSamplePanel” для панели UI.
В функциях register и unregister мы управляем подключением аддона в Blender API.
Можно установить получившийся аддон и проверить его работу – по нажатию на кнопку “Add Cube” в сцену будет добавлен дефолтный куб.
Для того, чтобы добавить в аддон глобальные параметры, нужно создать новый класс, наследовав его от bpy.types.AddonPreferences:
1 2 |
class addCubeSamplePreferences(bpy.types.AddonPreferences): bl_idname = __name__ |
Весь наш аддон размещается в одном файле (модуле), поэтому в качестве идентификатора bl_idname указывается имя текущего модуля аддона “__name__”.
Если вы создаете параметры для многофайлового аддона, вместо имени модуля нужно указывать имя пакета аддона:
1 2 |
class addCubeSamplePreferences(bpy.types.AddonPreferences): bl_idname = __package__ |
Для примера определим параметр, который будет влиять на общий ход работы аддона – при активации его пользователем на созданный куб будет автоматически накладываться модификатор Bevel.
Для этого внутри класса-свойства опишем сам параметр. Параметры создаются точно так же, как и для классов-операторов, используя типы, описанные в bpy.props: StringProperty, IntProperty, BoolProperty и т.д.
Для наглядности сделаем переключатель вида “RadioButton” с двумя вариантами выбора: “Add Bevel” – добавлять модификатор на создаваемый куб, и “No Bevel” – не добавлять.
1 2 3 4 5 6 7 |
add_bevel: bpy.props.EnumProperty( items=[ ('bevel', 'Add bevel', '', '', 0), ('no_bevel', 'No Bevel', '', '', 1) ], default='no_bevel' ) |
Имя параметра “add_bevel”, предустановленное значение – модификатор не добавляется.
Для того, чтобы отобразить параметр в панели свойств аддона, нужно переопределить функцию “draw” на отрисовку созданного параметра. Отрисовка пользовательского интерфейса для панели свойств аддона производится точно так же, как и для обычных панелей.
1 2 3 4 5 |
def draw(self, context): layout = self.layout layout.label(text='Add bevel modifier:') row = layout.row() row.prop(self, 'add_bevel', expand=True) |
Здесь мы добавили текстовое поле “label” с описанием параметра и вывели сам параметр “add_bevel” в виде переключателя.
Класс панели свойств аддона так же нужно зарегистрировать в функции “register” и разрегистрировать в функции “unregister”.
Для того, чтобы в классе-операторе получить текущее значение параметра из панели свойств аддона, нужно обратиться к нему, указав имя аддона и имя параметра. Следующий код вернет текущее значение свойства “add_bevel” нашего аддона.
1 |
bpy.context.preferences.addons['test'].preferences.add_bevel |
Добавим дополнительное условие для создания модификатора при нужном значении параметра “add_bevel” в классе-операторе “addCubeSample:
1 2 |
if context.preferences.addons['test'].preferences.add_bevel == 'bevel': bpy.ops.object.modifier_add(type='BEVEL') |
Окончательный код аддона теперь имеет следующий вид:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
import bpy bl_info = { 'name': 'test', 'category': 'All', 'author': 'Korchiy', 'version': (0, 0, 1), 'blender': (2, 80, 0), 'location': '3D_Viewport window -> N-Panel > Test', 'description': 'Test' } class addCubeSample(bpy.types.Operator): bl_idname = 'mesh.add_cube_sample' bl_label = 'Add Cube' bl_options = {"REGISTER", "UNDO"} def execute(self, context): bpy.ops.mesh.primitive_cube_add() if context.preferences.addons['test'].preferences.add_bevel == 'bevel': bpy.ops.object.modifier_add(type='BEVEL') return {"FINISHED"} class addCubeSamplePanel(bpy.types.Panel): bl_idname = 'test.panel' bl_label = 'TEST' bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'TEST' def draw(self, context): self.layout.operator("mesh.add_cube_sample", icon='MESH_CUBE', text="Add Cube") class addCubeSamplePreferences(bpy.types.AddonPreferences): bl_idname = __name__ add_bevel: bpy.props.EnumProperty( items=[ ('bevel', 'Add bevel', '', '', 0), ('no_bevel', 'No bevel', '', '', 1) ], default='no_bevel' ) def draw(self, context): layout = self.layout layout.label(text='Add bevel modifier:') row = layout.row() row.prop(self, 'add_bevel', expand=True) def register(): bpy.utils.register_class(addCubeSample) bpy.utils.register_class(addCubeSamplePanel) bpy.utils.register_class(addCubeSamplePreferences) def unregister(): bpy.utils.unregister_class(addCubeSamplePreferences) bpy.utils.unregister_class(addCubeSamplePanel) bpy.utils.unregister_class(addCubeSample) if __name__ == '__main__': register() |
После его установки в окне “Preferences” под панелью аддона появится дополнительная панель с его свойствами.
Если пользователь установит значение переключателя в “Add Bevel” и сохранит настройки, нажав на кнопку “Save Preferences”, дефолтный куб, созданный при помощи нашего аддона по умолчанию будет создаваться с модификатором “Bevel”.