3
$\begingroup$

I'm working on an Addon that saves Render Settings and Camera Settings.

If I try to save camera settings but the multiview in the Output Settings is not set to True, it gives an error, because the Stereoscopy Settings in the Camera-Properties are non existing.

I found out because it is not possible to get values from the context inside of a class.

How can I make an if statement happen by looking for a boolean value in Blender context?

This example is a copy from the Blender API, just to make it work in a small txt-file. Look for the if statement with ##<-------- here is the question.

import bpy
from bpy.types import Operator, Menu
from bl_operators.presets import AddPresetBase


class OBJECT_MT_display_presets(Menu):
    bl_label = "Object Display Presets"
    preset_subdir = "object/display"
    preset_operator = "script.execute_preset"
    draw = Menu.draw_preset


class AddPresetObjectDisplay(AddPresetBase, Operator):
    '''Add a Object Display Preset'''
    bl_idname = "camera.object_display_preset_add"
    bl_label = "Add Object Display Preset"
    preset_menu = "OBJECT_MT_display_presets"

    # variable used for all preset values
    preset_defines = [
        "obj = bpy.context.object"
        "data = bpy.context.data"

    ]

    # properties to store in the preset
    preset_values = [
        "obj.display_type",
        "obj.show_bounds",
        "obj.display_bounds_type",
        "obj.show_name",
        "obj.show_axis",
        "obj.show_wire",
    ]

######################
######################

    if bpy.context.scene.render.use_multiview == True:  ##<--------here is the question
        self.preset_values.extend([
            "data.stereo.convergence_mode",
            "data.stereo.convergence_distance",
            "data.stereo.interocular_distance",
            "data.stereo.use_spherical_stereo",
        ])
        
#####################
#####################

    # where to store the preset
    preset_subdir = "object/display"


# Display into an existing panel
def panel_func(self, context):
    layout = self.layout

    row = layout.row(align=True)
    row.menu(OBJECT_MT_display_presets.__name__, text=OBJECT_MT_display_presets.bl_label)
    row.operator(AddPresetObjectDisplay.bl_idname, text="", icon='ZOOM_IN')
    row.operator(AddPresetObjectDisplay.bl_idname, text="", icon='ZOOM_OUT').remove_active = True


classes = (
    OBJECT_MT_display_presets,
    AddPresetObjectDisplay,
)


def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.OBJECT_PT_display.prepend(panel_func)


def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
    bpy.types.OBJECT_PT_display.remove(panel_func)


if __name__ == "__main__":
    register()
$\endgroup$
4
  • 1
    $\begingroup$ Where is context defined? Not my area.. but should that be bpy.context? $\endgroup$
    – Robin Betts
    Jan 6, 2021 at 12:46
  • 1
    $\begingroup$ Thanks, I've edited the Question. But that was not the problem, just a little typo here in the Qestion.(It's not the orignal script I'm working on, just a short as possible version of it - sorry for that typo.) $\endgroup$
    – Andi
    Jan 6, 2021 at 13:02
  • 1
    $\begingroup$ Could use the poll classmethod to populate list based on context, the class is only defined once. $\endgroup$
    – batFINGER
    Jan 6, 2021 at 13:23
  • $\begingroup$ Thank you batFINGER, sadly I have no idea how to do that. Can you please give me an example with the code in the question? This poll feature is over my head for now... already made some tests with it, but without a useful result. $\endgroup$
    – Andi
    Jan 6, 2021 at 13:28

1 Answer 1

1
$\begingroup$

After a long while I finally understand it:

It's not possible to get the context inside a Class outside a function, (except of batFINGER's way, but I still don't understand that). But it is possible to get what ever is needed in a function outside the class and then use the function like this: (Here is only the relevant part of the script shown) -----> In this way, the context won't update. Therefore the way over the "@classmethod def poll(cls,context) is needed. (not shown here)

import bpy

def Multiview():
    if bpy.context.scene.render.use_multiview == True:
        print('Yes, its true')
        return True
    else:
        return False

class AddPresetObjectDisplay(AddPresetBase, Operator):
    '''Add a Object Display Preset'''
    bl_idname = "camera.object_display_preset_add"
    bl_label = "Add Object Display Preset"
    preset_menu = "OBJECT_MT_display_presets"

    # variable used for all preset values
    preset_defines = [
        "obj = bpy.context.object"
        "data = bpy.context.data"

    ]

    # properties to store in the preset
    preset_values = [
        "obj.display_type",
        "obj.show_bounds",
        "obj.display_bounds_type",]

    if Multiview():          ####<------- Context used here
        preset_values.extend([

        "obj.show_name",
        "obj.show_axis",])

Or another useful example:

def Blender_2_93():
    if bpy.app.version >= (2,93,0):
        return True
    else:
        return False

With that little function is it very easy to make changes for different blender versions if a preset system is used or something else where the access to context, data or what ever is not usual.

$\endgroup$
2
  • 1
    $\begingroup$ To elaborate on "my method" .. AddPresetObjectDisplay.preset_defines is a class property. The poll method is a class method def poll(cls, context) where you can set class properties eg if context.foo: cls.bar = [1, 2, 3] ... whereas the method above will define the list once based on the context when defined, and will not work as expected during restricted context on addon registration. $\endgroup$
    – batFINGER
    May 19, 2021 at 12:37
  • $\begingroup$ Looks like I need to edit my answer... It will work great to get the blender version, but I didn't now its not updating if a property or something is called. In your example, if context.foo: cls.bar = [1,2,3] , how can I access the data afterwards? I probably miss some knowledge about this task, because I'm still not able to understand. $\endgroup$
    – Andi
    May 19, 2021 at 12:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .