How can I call the active brush within my script? 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
The value you get with brush = bpy.context.tool_settings.sculpt.brush is a Brush object:

&gt;&gt;&gt; type(bpy.context.tool_settings.sculpt.brush)
&lt;class 'bpy.types.Brush'&gt;


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