1
$\begingroup$

I am trying to automate the task of creating an eraser brush in blender via python, as part of another operator.

I want to look for brush named 'ERASER' and switch to it, or create one and make it the active brush if not.

I found a few things online, but it looks more like sculpt brushes are easier to handle data wise than image paint/texture paint brushes. I am hoping someone might point me in the correct way of handling this.

Thanks in advance for help.

Current code snippet:

class GenericOper(bpy.types.Operator):
"""Generic Operator"""
bl_idname = "object.generic_operator" 


bl_label = "Generic Operator Template"
bl_options = { 'REGISTER', 'UNDO' }

def execute(self, context):

    scene = context.scene


    #new code

    #bpy.ops.paint.texture_paint_toggle()
    bpy.ops.paint.brush_select(paint_mode='ACTIVE', texture_paint_tool='DRAW')
    bpy.ops.brush.add()
    bpy.data.brushes["TexDraw.001"].name="ERASER"
    bpy.context.scene.tool_settings.unified_paint_settings.use_pressure_size = False
    bpy.data.brushes["ERASER"].use_pressure_strength = False
    bpy.data.brushes["ERASER"].blend = 'ERASE_ALPHA'


    return {'FINISHED'}
$\endgroup$
2
  • $\begingroup$ Someone pointed me to an answer (proxe) --- context.tool_settings.image_paint.brush = bpy.data.brushes[name] $\endgroup$ Commented Dec 29, 2016 at 0:45
  • 1
    $\begingroup$ Instead of ops you could do brush = bpy.data.brushes.new('ERASER') Then you have your brush in a variable, so- brush.blend = "ERASE_ALPHA" and so on. $\endgroup$
    – cmomoney
    Commented Dec 29, 2016 at 1:34

1 Answer 1

5
$\begingroup$

If it can be avoided, it is better to not use operators inside an operator. You should not use bpy.context in the operator, instead use the context parameter that is passed in, this allows a context to be overridden and if calling other operators should be passed along.

To find an existing erase brush you can loop over the brushes found in bpy.data.brushes and see if any that are set to be used in texture painting (use_paint_image is True) and the blend mode is Erase Alpha then you can set it as the active brush in the tool settings that you have found. If no erase brushes are found, you can create a new one. Checking the name of a brush is unreliable as the user may change it to anything, such as "gomme" being french for eraser.

def execute(self, context):
    # get a list of erase alpha brushes
    erase_brushes = [b for b in bpy.data.brushes
                if b.use_paint_image and b.blend == 'ERASE_ALPHA']
    if len(erase_brushes):
        # if we have more than one just use the first
        use_brush = erase_brushes[0]
    else:
        # create an erase alpha brush
        use_brush = bpy.data.brushes.new('AlphaErase')
        use_brush.blend = 'ERASE_ALPHA'
        use_brush.use_pressure_strength = False

    context.scene.tool_settings.unified_paint_settings.use_pressure_size = False
    context.tool_settings.image_paint.brush = use_brush
    return {'FINISHED'}
$\endgroup$
1
  • $\begingroup$ Thank you for the example. In my case, I need to create a brush from the default Draw tool, and make it use the settings shown for an eraser. Polling for 'ERASE_ALPHA' might seem okay, except if the available result is a Fill tool, and that won't work for the purpose intended. As the brush is not saved as Fake User, it can be created and then dropped out, not affecting the possible saved brushes in startup. I will look at your example and see if I can modify it to work, as it is very close to what I had hoped was a possibility. $\endgroup$ Commented Dec 30, 2016 at 13:10

You must log in to answer this question.

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