user3052391
user3052391

Reputation: 105

How to access variable of other user Class(blender python)?

I want to access variable of other Class. Static variable of other Class was very good accessed. But dynimic changed variable value of ther Class was not good accessed.

Why I can't get the changed variable value?


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()

Upvotes: 0

Views: 3425

Answers (2)

nate_39
nate_39

Reputation: 1

I assume that

testInstance = SelectFace() # why not work?

is the real question.

see: https://www.blender.org/api/blender_python_api_2_60a_release/info_overview.html

seems it is not expected that you write code that creates an instance of an bpy.types.Operator. Perhaps Blender handles bpy.types.Operator sub class creation in its own way.

"Notice these classes don’t define an init(self) function. While init() and del() will be called if defined, the class instances lifetime only spans the execution. So a panel for example will have a new instance for every redraw, for this reason there is rarely a cause to store variables in the panel instance. Instead, persistent variables should be stored in Blenders data so that the state can be restored when blender is restarted."

see also, Property Definitions: https://www.blender.org/api/blender_python_api_2_66a_release/bpy.props.html

Upvotes: 0

sambler
sambler

Reputation: 7079

An operator in blender is used to perform an action. While we use a class to define that action and related properties, we shouldn't treat them as normal python classes. The properties of an operator should be used to adjust the action peformed, not to hold variable data.

As the operators properties control the result of the operator, they are used by blender to perform undo/redo steps. These properties are also adjustable by the user using the operator properties panel by pressing F6 and can also be found at the bottom of the toolbar region.

operator properties

Add bl_options = {'REGISTER', 'UNDO'} to your operator to allow a user to adjust your operator. You can also customise the display within this panel by giving your operator a draw(self,context) method.

To control how an operator performs it's task when we call it directly, we can add the properties to the operator call -

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

If you are adding an operator button to a panel you can use -

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

or if you need to set multiple values you can use -

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

The example you provided uses a property that appears to only be valid for one object, if the user selects another object it will no longer be valid. This property would work better as an object property, you can add a property to the object class (or several others listed as subclasses of ID) by adding it in your addons register() and removing it in unregister()

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

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

For that example you could even count the selected faces when you needed the value -

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

Upvotes: 0

Related Questions