How to transfer uv_layers to another object? (2.6.3 bMesh)

Hi All,

I am looking for a way to transfer UV maps from one mesh based object to another mesh based object that was derived from the original source. The goal is to extend the 3Delight exporter. As of version 0.76 it does not support multi-material meshes (boo hoo). I managed to write code that will examine the original object and make a new object for each material that is only made up of the faces that each material is applied to. When I run the code, it converts one mesh to many and that part works fine.

The problem I am having is that because each of these new objects have new datablocks there is no connection to the UV maps applied to the original source object.

I am not sure how to copy uv_layers from one object to another. Let’s assume the two objects have the same number of vertices.

I tried


targetOb.data.uv_layers.new()
uvl = sourceOb.data.uv_layers[0]
targetOb.data.uv_layers[0] = uvl

This does not work for a couple of reasons, but it illustrates what I want to do. I want to create a new UV layer on the targetOb and copy the UV layer from the sourceOb to it.

Does anyone have any tips on how to do this?

Thanks

I had to do similar in the project I’m working on, in which a given material has one to four texture layers, each with its own UV’s. My routine typically kicks in when upping the layer count. Though it can happen in some reduction instances. Anyway, I saved a copy of the UV’s to separate array. Then copy them back as needed.

Sample code to save UVs. Mesh is a, well, mesh. Slot is the number position of the UV layer. TUVLayer is essentially an array of UV values.


def SaveUVLayer(Mesh,Slot):
             datum = TUVLayer()
             UVLayer = Mesh.uv_layers[Slot].data
             for poly in Mesh.polygons:
                     for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
                             datum.uv[loop_index] = UVLayer[loop_index].uv.copy()
             return datum

Sample Code to insert UVs. Slot is the layer number receiving the data. The Layer.uv bit is the datum variable from above. LName is the name given to the layer.


        UVLayer = Mesh.uv_textures.new(LName)
        UVLoop = Mesh.uv_layers[Slot]
        for poly in Mesh.polygons:
                 UVLayer.data[poly.index].image = meshTexture.texture.image
                 for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
                         UVLoop.data[loop_index].uv = Layer.uv[loop_index]
        UVLayer.active = True
        Mesh.update()

The for loops could probably be reduced to:

for loop_index in poly.loop_indices:

Thanks for the info, but I’m not sure how to re-arrange your code to do what I need.
For instance, what is Layer in this line of code?

UVLoop.data[loop_index].uv = Layer.uv[loop_index]

I can gather the uvs from the source mesh like so.


uvs = []
for uv_layer in me_source.uv_layers:
    for x in range(len(uv_layer.data)):
        uvs.append(uv_layer.data[x].uv)

But how do I deploy these back to the target mesh?

“Layer” in my code is the stored UV’s. I should state that my code represents two different sections of a much larger routine, which are called functions. I have the possibility of saving up to four diffuse layers, one normal layer, one specular layer and one cube map layer. Anyway, it would be replaced by the “uvs” list in your code. A sample mixture of the two:


        UVLayer = Mesh.uv_textures.new(LName)
        UVLoop = Mesh.uv_layers[Slot]
        for poly in Mesh.polygons:
                UVLayer.data[poly.index].image = meshTexture.texture.image
                for loop_index in loop_indices:
                        UVLoop.data[loop_index].uv = uvs[loop_index]

Oh, I forgot to mention the meshTexture variable previously. It is, of course, the texture used by the mesh.

Thanks for the help!

Here is what I have so far…


print("Reading UVs")
uvs = []
for uv_layer in me_source.uv_layers:
    for x in range(len(uv_layer.data)):
        uvs.append(uv_layer.data[x].uv)

print("Writing UVs")
UVLoop = me_target.uv_layers[0]
for poly in me_target.polygons:
    for loop_index in loop_indices:
        UVLoop.data[loop_index].uv = uvs[loop_index]

This code errors out here:

UVLoop = me_target.uv_layers[0]

Because a new mesh does not have any uv_layers. How do I create a new uv_layer?
There appears to be no append or new method.

Try:


print("Writing UVs")
UVLayer = me.uv_textures.new('Example New Layer')#Add a layer
UVLoop = me_target.uv_layers[len(me.uv_textures)-1]#I can't find an 'index' value, so point to last in line
for poly in me_target.polygons:
        for loop_index in loop_indices:
                UVLoop.data[loop_index].uv = uvs[loop_index]