Как получить доступ к переменной другого пользовательского класса (blender python)?

Я хочу получить доступ к переменной другого класса. Статическая переменная другого класса была очень хорошо доступна. Но измененное значение переменной класса Class не было доступным.

Почему я не могу получить измененное значение переменной?


bl_info = {
    "name": "New Object",
    "author": "Your Name Here",
    "version": (1, 0),
    "blender": (2, 75, 0),
    "location": "View3D > Add > Mesh > New Object",
    "description": "Adds a new Mesh Object",
    "warning": "",
    "wiki_url": "",
    "category": "Add Mesh",
}

import bpy

class SelectFace(bpy.types.Operator):
    bl_idname = "object.d0"
    bl_label = "Select Face"

    selected_faces = 2

    def __init__(self):
        self.selected_faces = 3

    def execute(self, context):
        print("self.selected_faces: ", self.selected_faces)
        self.selected_faces +=  1
        bpy.ops.object.d1('INVOKE_DEFAULT')
        return {'FINISHED'}

class OperationAboutSelectedFaces(bpy.types.Operator):
    """ Test dialog. """
    bl_idname = "object.d1"
    bl_label = "Test dialog"

    F_num = bpy.props.IntProperty(name="be Selected face", default=1)

    @classmethod 
    def poll(self, context):
        obj = context.object
        return(obj and obj.type == 'MESH' and context.mode == 'OBJECT')

    def invoke(self, context, event):        

        # This block code is Not Work!  ---  TypeError: bpy_struct.__new__(type): expected a single argument.
        testInstance = SelectFace()   #  why not work?
        print("testInstance.selected_faces: ", testInstance.selected_faces)
        self.F_num = testInstance.selected_faces

        # This block code is nice Work!
        testInstance = SelectFace.selected_faces
        print("testInstance: ", testInstance)
        self.F_num = testInstance

        return context.window_manager.invoke_props_dialog(self)

    def execute(self, context):
        context.active_object.data.polygons [self.F_num].select = True
        return {'FINISHED'}  

    def register():
        bpy.utils.register_class(SelectFace)
        bpy.utils.register_class(OperationAboutSelectedFaces)

    def unregister():
        bpy.utils.unregister_class(SelectFace)
        bpy.utils.unregister_class(OperationAboutSelectedFaces) 

    if __name__ == "__main__":
        register()
        bpy.ops.object.d0()

2 ответа

Оператор в блендере используется для выполнения действия. Хотя мы используем класс для определения этого действия и связанных свойств, мы не должны рассматривать их как обычные классы Python. Свойства оператора должны использоваться для настройки выполняемого действия, а не для хранения переменных данных.

Поскольку свойства операторов контролируют результат оператора, они используются blender для выполнения шагов отмены / повтора. Эти свойства также настраиваются пользователем с помощью панели свойств оператора нажатием клавиши F6 и также находятся в нижней части области панели инструментов.

свойства оператора

добавлять bl_options = {'REGISTER', 'UNDO'} своему оператору, чтобы пользователь мог настроить вашего оператора. Вы также можете настроить отображение на этой панели, предоставив оператору draw(self,context) метод.

Чтобы контролировать, как оператор выполняет свою задачу, когда мы вызываем его напрямую, мы можем добавить свойства к вызову оператора -

bpy.ops.object.d1(F_num=4, val2=3.6)

Если вы добавляете кнопку оператора на панель, вы можете использовать -

row.operator('object.d1').F_num = 4

или если вам нужно установить несколько значений, которые вы можете использовать -

op = row.operator('object.d1')
op.F_num = 4
op.val2 = 3.6

В приведенном вами примере используется свойство, которое представляется действительным только для одного объекта. Если пользователь выберет другой объект, оно больше не будет действительным. Это свойство будет работать лучше как свойство объекта, вы можете добавить свойство к классу объекта (или нескольким другим, перечисленным как подклассы ID), добавив его в свои дополнения register() и удалив его в unregister()

def register():
    bpy.types.Object.selected_faces = bpy.props.IntProperty()

def unregister():
    del bpy.types.Object.selected_faces

Для этого примера вы можете даже считать выбранные лица, когда вам нужно значение -

selected_faces_count = len([f for f in obj.data.polygons if f.select])

Я предполагаю что

testInstance = SelectFace() # почему не работает?

это реальный вопрос.

см.: https://www.blender.org/api/blender_python_api_2_60a_release/info_overview.html

кажется, не ожидается, что вы пишете код, который создает экземпляр bpy.types.Operator. Возможно, Blender по-своему обрабатывает создание подкласса bpy.types.Operator.

"Обратите внимание, что эти классы не определяют функцию init(self). Хотя init() и del() будут вызываться, если они определены, время жизни экземпляров класса охватывает только выполнение. Так, например, панель будет иметь новый экземпляр для каждого перерисовать, по этой причине редко есть причина хранить переменные в экземпляре панели. Вместо этого постоянные переменные должны храниться в данных Blenders, чтобы можно было восстановить состояние при перезапуске Blender."

см. также "Определения свойств": https://www.blender.org/api/blender_python_api_2_66a_release/bpy.props.html

Другие вопросы по тегам