4
$\begingroup$

I am attempting to modify sculpt brush settings via a custom menu. To do this I'm setting a string property to specify the setting I wish to modify.

Since these settings are dependent on the active brush, I need to pull in the current brush via:

bpy.context.tool_settings.sculpt.brush

It seems this should work. I can confirm that it's accessing the correct brush. However, when I assign the brush context to a variable, and then call that variable within the data path it complains:

Traceback (most recent call last): File "/stringProp-tool.py", line 16, in execute TypeError: bpy_prop_collection[key]: invalid key, must be a string or an int, not Brush

Here is my script:

import bpy

class BrushSettings(bpy.types.Operator):
    """Toggle Setting For Active Brush"""
    bl_idname = "sculpt.brush_setting"
    bl_label = "Toggle Brush Setting"

    setting = bpy.props.StringProperty()

    def execute(self, context):

        setting = self.setting
        brush = bpy.context.tool_settings.sculpt.brush

        if setting == 'use_accumulate':
            value = bpy.data.brushes[brush].use_accumulate
            print(value)
            bpy.data.brushes[brush].use_accumulate = not value
        return {"FINISHED"}


class BrushSettingsMenu(bpy.types.Menu):
    bl_label = "Brush Settings"
    bl_idname = "sculpt.brush_settings_menu"

    def draw(self, context):
        layout = self.layout

        accumulate = layout.operator("sculpt.brush_setting", "Accumulate")
        accumulate.setting = 'use_accumulate'

def register():
    bpy.utils.register_class(BrushSettings)
    bpy.utils.register_class(BrushSettingsMenu)

def unregister():
    bpy.utils.unregister_class(BrushSettings)
    bpy.utils.unregister_class(BrushSettingsMenu)


if __name__ == "__main__":
    register()

    bpy.ops.wm.call_menu(name=BrushSettingsMenu.bl_idname)

The lines giving me grief are these:

value = bpy.data.brushes[brush].use_accumulate
bpy.data.brushes[brush].use_accumulate = not value
$\endgroup$

2 Answers 2

8
$\begingroup$

The value you get with brush = bpy.context.tool_settings.sculpt.brush is a Brush object:

>>> type(bpy.context.tool_settings.sculpt.brush)
<class 'bpy.types.Brush'>

When you access bpy.data.brushes[brush] it expects a name string (i.e. brush.name). Instead you can simply use the brush itself:

def execute(self, context):

    setting = self.setting
    brush = bpy.context.tool_settings.sculpt.brush
    print(brush)

    if setting == 'use_accumulate':
        value = brush.use_accumulate
        print(value)
        brush.use_accumulate = not value
    return {"FINISHED"}

One more suggestion:

Use the supplied context of the operator, this is better than using bpy.context:

brush = context.tool_settings.sculpt.brush
$\endgroup$
0
2
$\begingroup$

Accessing data via collection look-up they expects a string or an int: That is why you got the error.

bpy_prop_collection[key]: invalid key, must be a string or an int, not Brush

Running the following in the console window we can see that setting variable gets assigned a bpy.type.brush

>>> type(bpy.context.tool_settings.sculpt.brush)
<class 'bpy.types.Brush'>

Its a simple fix, you need to use the name of the brush.

value = bpy.data.brushes[brush.name].use_accumulate

However, obviously in this case you better just use.

value = brush.use_accumulate
$\endgroup$

You must log in to answer this question.

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