4
$\begingroup$

I need to change indexes for UVMaps. Here the screenshot:

enter image description here

I tried like this, according to ths page https://stackoverflow.com/questions/2493920/how-to-switch-position-of-two-items-in-a-python-list :

import bpy

cubeObject = bpy.context.scene.objects[0]
cubeObject.data.uv_textures[0], cubeObject.data.uv_textures[1] = cubeObject.data.uv_textures[1], cubeObject.data.uv_textures[0]

But I got this Exception:

read blend: /home/mifth/Desktop/2223/uvs.blend
Traceback (most recent call last):
File "/home/mifth/Desktop/2223/uvs.blend/Text", line 4, in <module>
IndexError: bpy_prop_collection[index] = value: failed assignment (unknown reason)

This is very important for exporting models to game engines like Unity, Unreal, jMonkey, Ogre3D...

Thanks.

$\endgroup$
6
$\begingroup$

According to the blender 2.69 python API reference, uv_textures is a bpy_prop_collection of MeshTexturePolyLayer and it is read only. It would appear to be accessed in Python as a dictionary of key/value pairs (try bpy.context.active_object.data.uv_textures.items() in Blender's Python console). This would be why the array re-ordering techniques fail to work.

I'm not sure that this is the best way but it appears to work. Test to see if it fixes the export order.

import bpy

mesh = bpy.context.active_object.data

mesh.uv_textures.active_index = 0
tmpuvmap = mesh.uv_textures.active
tmpuvmap_name = tmpuvmap.name

newuvmap = mesh.uv_textures.new()
mesh.uv_textures.remove(tmpuvmap)
newuvmap.name = tmpuvmap_name

By setting active_index = 0, the call to new() duplicates the first UVMap, putting a duplicate of it at the end before deleting the first item.

This appears to give the same result as manually selecting the first item, clicking + to create a new UVMap then deleting the first item within blender.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you a lot! This way works. But it seems blender has a bug in renaming... Even if the object is removed I cannot name the new one with the same name. So that i must change your last code line: mesh.uv_textures[len(mesh.uv_textures) - 1].name = tmpuvmap_name $\endgroup$ – mifth Dec 8 '13 at 19:48
  • $\begingroup$ I reported this issue, but the dev said it's python limitation developer.blender.org/T37749 $\endgroup$ – mifth Dec 10 '13 at 9:18
1
$\begingroup$

Old thread but...This script works, I dont have time to make it as a AddOn, To use it, select the UvMap and then run this script

###################################################
#  UvMaps must be less than 8 because its use a
#  free map to reorder
#  Select the UvMap and Run this script (Alt + P)
#  I guess 8 Uvmaps is Blender's limit
#  Author: Victor Botelho (vlab22@gmail.com)
#
#  Steps this script does:
#  1. Duplicate de select UvMap (it goes to
#  the bottom uv index), delete the original
#  UvMap and rename the duplicated.
#
#  2. Duplicate the UvMap above the original
#  (already deleted) and does the same (delete
#  and rename)
#
#  3. Walks down each UvMap above "the original"
#  and does the same (duplicate, delete and rename)
###################################################

import bpy

uvTexts = bpy.context.object.data.uv_textures

acInx= bpy.context.object.data.uv_textures.active_index

if len(uvTexts) > 0 and len(uvTexts) < 8 and acInx > 0:

    uv = bpy.context.object.data.uv_textures.active
    uvActive = bpy.context.object.data.uv_textures.active_index
    print("uvActive: " + str(uvActive))
    uvName = uv.name

    uvTexts = bpy.context.object.data.uv_textures
    uvLoop = len(uvTexts) - uvActive - 1

    #Add a copy
    bpy.ops.mesh.uv_texture_add()

    bpy.context.object.data.uv_textures.active_index = uvActive

    #Remove old
    bpy.ops.mesh.uv_texture_remove()

    uvTexts = bpy.context.object.data.uv_textures

    bpy.context.object.data.uv_textures.active_index = len(uvTexts)-1

    uv = bpy.context.object.data.uv_textures.active
    uv.name = uvName

    #Add a copy
    bpy.context.object.data.uv_textures.active_index = uvActive - 1
    uvActive = bpy.context.object.data.uv_textures.active_index
    print("uvActive: " + str(uvActive))
    uv = bpy.context.object.data.uv_textures.active
    uvName = uv.name

    bpy.ops.mesh.uv_texture_add()

    bpy.context.object.data.uv_textures.active_index = uvActive

    #Remove Old
    bpy.ops.mesh.uv_texture_remove()

    uvTexts = bpy.context.object.data.uv_textures

    bpy.context.object.data.uv_textures.active_index = len(uvTexts)-1

    uv = bpy.context.object.data.uv_textures.active
    uv.name = uvName

    #Walk Down until
    limitInx = len(uvTexts)-2

    for i in range(0,uvLoop):
        print("for: " + str(i))
        bpy.context.object.data.uv_textures.active_index = uvActive
        uv = bpy.context.object.data.uv_textures.active
        uvName = uv.name

        bpy.ops.mesh.uv_texture_add()

        bpy.context.object.data.uv_textures.active_index = uvActive

        #Remove
        bpy.ops.mesh.uv_texture_remove()

        uvTexts = bpy.context.object.data.uv_textures

        bpy.context.object.data.uv_textures.active_index = len(uvTexts)-1

        uv = bpy.context.object.data.uv_textures.active
        uv.name = uvName

    bpy.context.object.data.uv_textures.active_index = uvActive
else:
    if (len(uvTexts) > 7):
        print("Maximum UvMaps permitted is 7")
| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.