0
$\begingroup$

I'm trying to paint an image texture onto an object with bpy. I'm not running in background mode, so I can confirm the following:

  1. Object is loaded
  2. Image texture is loaded and added as a slot on the brush
  3. Image texture is set to stencil mode
  4. Image texture stencil is aligned with the mesh after some re-jiggering of the viewport (I can confirm this when the command line opens a blender window).

I now want to add strokes that paint the texture stencil onto the object, but having lots of trouble.

No matter what I do, the strokes don't show up on my object. However, I can easily paint the texture on manually. What is going on??

Note -- I tried some simple strokes that cross the viewport -- those didn't work. Now trying various stroke areas. But very confused. The context is correct (it was complaining before about that...)

    def get_override(area_type, region_type):
        # Find the specified area and region
        for window in bpy.context.window_manager.windows:
            screen = window.screen
            for area in screen.areas:
                if area.type == area_type:
                    for region in area.regions:
                        if region.type == region_type:
                            override = {
                                'window': window,
                                'screen': screen,
                                'area': area,
                                'region': region,
                                'space_data': area.spaces.active,
                                'blend_data': bpy.context.blend_data,
                                'scene': bpy.context.scene,
                                'tool_settings': bpy.context.tool_settings,
                                'view_layer': bpy.context.view_layer,
                                'workspace': bpy.context.workspace,
                                'region_data': area.spaces.active.region_3d if area.type == 'VIEW_3D' else None
                            }
                            return override
        return None
    override = get_override( 'VIEW_3D', 'WINDOW')
    bpy.ops.object.editmode_toggle()
    bpy.ops.paint.texture_paint_toggle()

    # Define the strokes to cover the viewport
    strokes = []
    for i in range(10):
        start_y = 500 + (i * 100)
        end_y = 500 + (i * 100)
        strokes.append({
            "name": f"stroke{i * 2 + 1}",
            "mouse": (0, start_y),  # Starting point in the viewport
            "mouse_event": (0, start_y),  # Starting point in the viewport
            "location": (0, 0, 0),  # Starting 3D location
            "pressure": 1.0,
            "size": 50,
            "pen_flip": False,
            "time": 1.0,
            "x_tilt": 0.0,
            "y_tilt": 0.0,
            "is_start": True,
        })
        strokes.append({
            "name": f"stroke{i * 2 + 2}",
            "mouse": (2000, end_y),  # Ending point in the viewport
            "mouse_event": (2000, end_y),  # Ending point in the viewport
            "location": (0, 0, 0),  # Ending 3D location
            "pressure": 1.0,
            "size": 50,
            "pen_flip": False,
            "time": 1.0,
            "x_tilt": 0.0,
            "y_tilt": 0.0,
            "is_start": False,
        })

    with bpy.context.temp_override(window=override['window'], screen=override['screen'], area=override['area'], region=override['region']):
        # print_context(    bpy.context)
        result = bpy.ops.paint.image_paint(stroke=strokes, mode='NORMAL')
        

Here's what I'm trying to do (the painted strokes were done manually): Soccer player texture stencil with green human mesh behind

$\endgroup$
6
  • $\begingroup$ Does the same work with strokes that are not applied through a stencil image? I mean, did you already get the code working as a way to deliver a square of texture paint strokes onto a texture target? $\endgroup$ Commented May 31 at 13:21
  • $\begingroup$ I really don't think this is the way you want to do whatever it is you're trying to do. Possibly an XY Question. Fiddling with overriding context and trying to recreate actual mouse movements and user actions with Python is almost always the worst way to go about solving a problem in Blender. Blender Scripting Gotchas. $\endgroup$
    – Jakemoyo
    Commented May 31 at 14:26
  • 1
    $\begingroup$ Tell us more about what end goal you're trying to accomplish instead of asking questions about fixing your specific solution, because there might be an easier way to pull off what you're shooting for. $\endgroup$
    – Jakemoyo
    Commented May 31 at 14:27
  • $\begingroup$ Sure, here's what' I'm trying to do: I have a character sheet with two images of the front and back of the character in a T-pose. I want to paint those them onto the front and back of my human_mesh.obj file. Then I want to download the resulting texture image so i can be applied to meshes on the fly $\endgroup$
    – jitsvm
    Commented May 31 at 14:49
  • $\begingroup$ Craig, no -- I couldn't paint any strokes onto the mesh even if the stencil was not added. $\endgroup$
    – jitsvm
    Commented May 31 at 14:52

0

You must log in to answer this question.