Sculpt programatically poll() context is incorrect

I would like to programatically sculpt to draw a perfect circle on the x/y axis and sculpt it into a dynotopo mesh.
I found this, but it gives me an error with the bpy.ops:

def sculptit(self, context, location):
tuple_location = tuple(location.strip("()").split(","))
stroke = [{ “name”: “defaultStroke”,
“mouse” : (0.0, 0.0),
“pen_flip” : False,
“is_start”: True,
“location”: tuple_location,
“pressure”: 1.0,
“time”: 1.0}]
#bpy.ops.sculpt.brush_stroke(stroke=stroke)

error is:
RuntimeError: Operator bpy.ops.sculpt.brush_stroke.poll() failed, context is incorrect

I found this:
https://docs.blender.org/api/blender_python_api_current/info_quickstart.html#operator-poll
and this:

neither of which were helpful, I can check that the context is incorrect or I can move the current window to a VIEW_3D context.
:\

1 Like

Anyone? I’m also having this same problem. As far as I can tell I am in SCULPT mode and yet this error still occurs. Is it a Blender bug?

I asked this at the Blender Conference and just didn’t follow up.


I’ll ask on the blender-dev mailing list and post back results here.
Pablo Dobarro mentioned he has a sculpt mode script that may handle this.

Here is an example of overriding context for an operator:

import bpy

def context_override():
    for window in bpy.context.window_manager.windows:
        screen = window.screen
        for area in screen.areas:
            if area.type == 'VIEW_3D':
                for region in area.regions:
                    if region.type == 'WINDOW':
                        return {'window': window, 'screen': screen, 'area': area, 'region': region, 'scene': bpy.context.scene} 
                    
bpy.ops.sculpt.brush_stroke(context_override())
import bpy
import time
def context_override():

    for window in bpy.context.window_manager.windows:
        screen = window.screen
        for area in screen.areas:
            if area.type == 'VIEW_3D':
                for region in area.regions:
                    if region.type == 'WINDOW':
                        return {'window': window, 'screen': screen, 'area': area, 'region': region, 'scene': bpy.context.scene} 


def sculptit( location):
    tuple_location = location#tuple(location[1:-1].split(","))
    stroke = [{ "name": "defaultStroke", 
    "mouse" : (3640, 1303),
    "pen_flip" : False,
    "is_start": True,
    "location": tuple_location,
    "size":100,
    "pressure": 10,
    "time": 1.0}]
    bpy.ops.sculpt.brush_stroke(context_override(),stroke=stroke)
    print("done")

#time.sleep(5)
#bpy.ops.wm.mouse_position('INVOKE_DEFAULT')
sculptit((0,0,0))

No error, but that’s if I’m in sculpt mode in the 3d view. It looks like I will have to have a window open for the wm , sculpt, and ops to do their thing. I cannot get a stroke to occur

In your test case, are you working with the default cube? I see you’re trying to add a stroke at (0,0,0). I’ve never used bpy.ops.sculpt.brush_stroke before, but I assume the location would need to be on the surface of a mesh.

Try this:

  1. Add and subdivide a cube (Since we’re about to sculpt, we need more detail in our mesh.)
  2. Call sculptit with a location of (0,-1,0) -> sculptit((0,-1,0))

Here is my result:
Selection_128

1 Like

That works! yay! Thanks Travisty!