12
$\begingroup$

I've made a script that creates a mesh in Blender using a binary file containing mesh data. That works fine, but now I need to get textures on the mesh and I want to create a UV map from the UV data in the file. However, I can't figure out how to add the UVs to the mesh.

Ideally, I'd like some system that lets me add a UV per vertex as I add the vertices. Should I be using UV loops? I don't really know what they are, but there is some information about BMLoopUV at the following url, although no example usage: http://www.blender.org/documentation/blender_python_api_2_67_release/bmesh.types.html#bmesh.types.BMLoopUV

$\endgroup$

2 Answers 2

9
$\begingroup$

There are 2 existing resources that show this:

The best is the template for this purpose that comes with blender 2.67:

See Text Editor -> Templates -> Python -> Operator UV.

There is also a snippet in BMesh docs.

$\endgroup$
6
  • $\begingroup$ Unfortunately I can't figure out how to get this working. I'm getting the error: "ReferenceError: BMesh data of type BMFace has been removed" on the line "for l in face.loops:" where face is the name of the face I just added to the mesh. Is there something special I need to do, or some state my mesh must be in for this to work? $\endgroup$
    – MrFlamey
    Commented Jun 9, 2013 at 8:35
  • $\begingroup$ "where face is the name of the face I just added to the mesh." should be "where face is is a reference to the face I just added to the mesh." $\endgroup$
    – MrFlamey
    Commented Jun 9, 2013 at 8:41
  • $\begingroup$ I checked on the template and it works fine in 2.67b, on a mesh in editmode. $\endgroup$
    – ideasman42
    Commented Jun 9, 2013 at 10:12
  • $\begingroup$ You are right. The template works fine, I just can't get it to work with my script :( Maybe I should add my code in a separate question and mark this answered? I have a feeling that I need to update the bmesh after adding the face, since the error mentioned above suggests something has gone missing. $\endgroup$
    – MrFlamey
    Commented Jun 9, 2013 at 11:11
  • $\begingroup$ Finally managed to get it working! Thanks for putting me on the right path. $\endgroup$
    – MrFlamey
    Commented Jun 9, 2013 at 13:25
4
$\begingroup$

Here is the code I wrote to add a face to a mesh. The function takes an object and a bmesh derived from the object's mesh data (obj.data), a list of vertices, uvs and the name of a texture/material. Using this data, the function adds a new face to the object.

The section where I am adding uvs is only slightly different to that in the example provided (see below). It is all written for Blender 2.67b. No idea if it works on older versions, but it's probably ok.


def mesh_append_face( obj, bm, vertex_list, uv_list, texture_name ):
    # add vertices and uvs before creating the new face
    for vert in vertex_list:
        bm.verts.new( ( vert[0], vert[1], vert[2] ) )
    bm.faces.new( ( bm.verts[i] for i in range( -len( vertex_list ), 0)) )

    # add uvs to the new face
    uv_layer = bm.loops.layers.uv.verify()
    bm.faces.layers.tex.verify()

    face = bm.faces[-1]
    for i, loop in enumerate(face.loops):
        uv = loop[uv_layer].uv
        uv[0] = uv_list[i][0]
        uv[1] = uv_list[i][1]

    # assign material
    try:
        material_names = [ m.name for m in obj.data.materials ]
        material_id = material_names.index(texture_name)
    except ValueError:
        obj.data.materials.append(bpy.data.materials[texture_name])
        material_id = len(obj.data.materials) - 1

    face.material_index = material_id

It is based on this example code from Text Editor -> Templates -> Python -> Operator UV:


def main(context):
    obj = context.active_object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)

    uv_layer = bm.loops.layers.uv.verify()
    bm.faces.layers.tex.verify()  # currently blender needs both layers.

    # adjust UVs
    for f in bm.faces:
        for l in f.loops:
            luv = l[uv_layer]
            if luv.select:
                # apply the location of the vertex as a UV
                luv.uv = l.vert.co.xy

    bmesh.update_edit_mesh(me)
$\endgroup$
2
  • $\begingroup$ I think this will work too: gist.github.com/anonymous/5750782 $\endgroup$
    – zeffii
    Commented Jun 10, 2013 at 17:48
  • $\begingroup$ Thanks. I'll try simplifying the code a bit next time I work on it. $\endgroup$
    – MrFlamey
    Commented Jun 11, 2013 at 14:51

You must log in to answer this question.

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