I am trying to create a textured polygon from python and have it display properly in the 3D View in Texture mode.

I can create the mesh, uv coordinates, object, material, texture, and image. If I select the "Rendered" display mode in the 3D View it shows the properly textured polygon. However, if I switch the 3D View to "Texture" display mode, the polygon is not showing texture but the material color.

This can be manually fixed by selecting the object, entering Edit mode, and switching to the UV/Image Editor (where the correct UV coordinates are already displayed) and selecting an image to be "linked" from the menu:

Image Link menu in UV/Image Editor

This causes the object to be properly displayed in the 3D View in Texture mode, but alas the python console and Console Window do not reveal what this does. Can anyone tell me what property of what kind of object is being set?

Below is the python code I am using to create the polygon and the materials/textures.

import bpy
from mathutils import Vector

def set_pixel(img: bpy.types.Image, x: int, y: int, color: list) -> None:
    width = img.size[0]
    offs = (x + int(y*width)) * 4
    for i in range(4):
        img.pixels[offs+i] = color[i]

def get_pixel(img: bpy.types.Image, x: int, y: int):
    width = img.size[0]
    offs = (x + y*width) * 4
    for i in range(4):
        color.append( img.pixels[offs+i] )
    return color

def doit():
    global mat
    global tex
    global slot
    global obj
    global image
    global mesh
    global uv_tex

        Vector((-1.0, -1.0, 0)),
        Vector(( 1.0, -1.0, 0)),
        Vector(( 1.0,  1.0, 0)),
        Vector((-1.0,  1.0, 0)) ]
    faces = [ (0, 1, 2, 3) ]
    name = 'my'

    # build mesh
    if name in bpy.data.meshes.keys():
    mesh = bpy.data.meshes.new(name)
    mesh.from_pydata(verts, [], faces)

    # build object
    if name in bpy.data.objects.keys():
    obj = bpy.data.objects.new(name, mesh)

    # add UV
    uv_name = name+'_uv'
    uv_tex = mesh.uv_textures.new(uv_name)
    vert_uvs = [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)]
             [uv for pair in
              [vert_uvs[l.vertex_index] for l in mesh.loops]
              for uv in pair])

    #generate image
    image_name = name+'_img'
    if image_name in bpy.data.images.keys():

    image = bpy.data.images.new(image_name, 4, 4, alpha=True)
    w = image.size[0]
    h = image.size[1]
    for x in range(w):
        for y in range(h):
            set_pixel(image, x, y, [1, 1, 0, 0])
    [set_pixel(image, 0, y, [0, 1, 0, 1]) for y in [0,3]]
    [set_pixel(image, x, 0, [0, 1, 1, 1]) for x in [1,2,3]]
    [set_pixel(image, 0, y, [0, 1, 1, 1]) for y in [1,2]]
    [set_pixel(image, x, 3, [0, 1, 1, 1]) for x in [1,2,3]]
    image.filepath_raw = "//" + image_name + ".png"

    # build texture
    tex_name = name+'_tex'
    if tex_name in bpy.data.textures.keys():
    tex = bpy.data.textures.new(tex_name, 'IMAGE')
    tex.use_preview_alpha = True
    tex.use_interpolation = False
    tex.extension = 'EXTEND'
    tex.filter_type = 'BOX'
    tex.use_mipmap = False
    tex.image = image

    # bulid material
    mat_name = name+'_mat'
    if mat_name in bpy.data.materials.keys():
    mat = bpy.data.materials.new(name=mat_name)
    mat.diffuse_color = [1, 1, 1]
    mat.use_transparency = True
    mat.transparency_method = 'RAYTRACE'

    # assign texture to material
    slot = mat.texture_slots.add()
    slot.blend_type = 'MULTIPLY'
    slot.use_map_alpha = True
    slot.texture_coords = 'UV'
    slot.uv_layer = uv_name
    slot.texture = tex

  • $\begingroup$ I observe that once the image is associate with the object/mesh I can actually delete the material and texture from the object and the 3D View display still shows the texture. $\endgroup$ – IRayTrace Jan 10 at 15:56

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.