Все определенные пользователем классы (панели, операторы), если они зарегистрированы в API, существуют только пока запущен сам графический редактор Blender. В момент закрытия программы все они удаляются из памяти. Поэтому, даже если внутри пользовательских классов определены какие-то переменные, все значения этих переменных при перезапуске программы будут сброшены.
Однако, иногда бывает необходимо использовать в аддоне Blender переменную, значение которой не будет потеряно в процессе перезапуска программы. Чтобы переменная сохраняла свое значение, нужно создать ее в виде специального класса – свойства (property), и присоединить к какому-либо объекту, свойства которого сохраняются в *.blend файле.
Создадим демонстрационный класс-свойство SampleVariables, который будет хранить внутри себя набор переменных.
Для того, чтобы превратить пользовательский класс в полноценное свойство, необходимо наследовать его от bpy.types.PropertyGroup. Для примера разместим внутри нашего класса две переменные variable1 (числового типа) и variable2 (логического типа), значение которых необходимо сохранять при выходе из программы. Тип этих двух переменных возьмем из bpy.props, чтобы можно было вынести их на панель и удобно изменять их значения.
1 2 3 4 5 6 7 8 9 10 11 |
class SampleVariables(bpy.types.PropertyGroup): variable1 = bpy.props.IntProperty( name="Var1", description="Sample variable 1", default=2 ) variable2 = bpy.props.BoolProperty( name="Var2", description="Sample variable 2", default=True ) |
Как и любой пользовательский класс, для включения в API класс-свойство необходимо зарегистрировать через register_class и разрегистрировать по окончании работы через unregister_class:
1 2 3 4 5 |
def register(): bpy.utils.register_class(SampleVariables) def unregister(): bpy.utils.unregister_class(SampleVariables) |
Также создадим панель SamplePanel, разместим ее в T-панели в области свойств, и вынесем на нее эти две переменные:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class SamplePanel(bpy.types.Panel): bl_idname = "panel.sample_panel" bl_label = "Panel for variable change" bl_space_type = "VIEW_3D" bl_region_type = "TOOL_PROPS" def draw(self, context): self.layout.prop(bpy.context.scene.sample_vars, 'variable1') self.layout.prop(bpy.context.scene.sample_vars, 'variable2') def register(): bpy.utils.register_class(SamplePanel) def unregister(): bpy.utils.unregister_class(SamplePanel) |
И, самое главное, класс-свойство нужно присоединить в качестве свойства к одному из сохраняемых в *.blend файле объектов. Для этого может послужить любой объект, к которому логически относятся данные переменные. В нашем примере они не привязаны ни к чему конкретному, поэтому сделаем их свойством всей сцены.
Привязку необходимо делать в момент регистрации:
1 2 |
def register(): bpy.types.Scene.sample_vars = bpy.props.PointerProperty(type=SampleVariables) |
и удалять в момент разрегистрации аддона:
1 2 |
def unregister(): del bpy.types.Scene.sample_vars |
Мы привязали наш пользовательский класс SampleVars в качестве свойства сцены sample_vars. Поэтому в классе-панели для взаимодействия с переменными в layout указывается объект bpy.context.scene.sample_vars.
Полный код демонстрационного аддона, который создает две переменные, привязывает их в качестве свойства к сцене и выводит на T-панель для изменения значений:
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 |
bl_info = { 'name': 'Saved Variables', 'category': 'All' } import bpy class SamplePanel(bpy.types.Panel): bl_idname = "panel.sample_panel" bl_label = "Panel for variable change" bl_space_type = "VIEW_3D" bl_region_type = "TOOL_PROPS" def draw(self, context): self.layout.prop(bpy.context.scene.sample_vars, 'variable1') self.layout.prop(bpy.context.scene.sample_vars, 'variable2') class SampleVariables(bpy.types.PropertyGroup): variable1 = bpy.props.IntProperty( name="Var1", description="Sample variable 1", default=2 ) variable2 = bpy.props.BoolProperty( name="Var2", description="Sample variable 2", default=True ) def register(): bpy.utils.register_class(SamplePanel) bpy.utils.register_class(SampleVariables) bpy.types.Scene.sample_vars = bpy.props.PointerProperty(type=SampleVariables) def unregister(): del bpy.types.Scene.sample_vars bpy.utils.unregister_class(SampleVariables) bpy.utils.unregister_class(SamplePanel) if __name__ == "__main__": register() |
Выведенные на панель переменные сохранят установленные значения после перезапуска Blender.