4
$\begingroup$

How to switch between UV maps on multiple objects at once? Example -- you have 300 assets, 1st UV channel for diffuse texture and 2nd for light map. If you want to edit all UV shells of the 1st channel on several objects in multi edit mode, you have to switch to this channel manually on every single active object one by one. Is there a Python script for doing it at once? I've checked StackExchange and other forums, but couldn't find the working solution.

This script seems fine, but it doesn't work for me: https://pastebin.com/wNWdUJdC

An example image of two objects: enter image description here

$\endgroup$

2 Answers 2

5
$\begingroup$

That's acutally pretty close. You just have to assign a MeshUVLoopLayer reference to MeshUVLoopLayer.active according to the API. Also I'd suggest exclude the active object from the loop and test whether there is an active layer within the poll method:

import bpy

class OBJECT_OT_set_active_uv(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.set_active_uv_selection"
    bl_label = "Set UV Layer on all Objects in Selection"
    bl_options = {'REGISTER', 'UNDO'}

    @classmethod
    def poll(cls, context):
        obj = context.active_object
        return obj is not None and obj.type == 'MESH' and obj.data.uv_layers.active

    def execute(self, context):        
        target_uv = context.active_object.data.uv_layers.active
        for obj in context.selected_objects:
            if obj.type == 'MESH' and obj != context.active_object:
                if target_uv.name in obj.data.uv_layers.keys():
                    # Active UV Layer = Target Layer
                    obj.data.uv_layers.active = obj.data.uv_layers[target_uv.name]
                    obj.data.uv_layers[target_uv.name].active_render = True

        return {'FINISHED'}


def draw_set_active_uv(self, context):
    layout = self.layout
    layout.operator(OBJECT_OT_set_active_uv.bl_idname)


def register():
    bpy.utils.register_class(OBJECT_OT_set_active_uv)
    bpy.types.DATA_PT_uv_texture.append(draw_set_active_uv)


def unregister():
    bpy.utils.unregister_class(OBJECT_OT_set_active_uv)
    bpy.types.DATA_PT_uv_texture.remove(draw_set_active_uv)


if __name__ == "__main__":
    register()
    # Test call
    #bpy.ops.object.set_active_uv_selection()
$\endgroup$
2
  • 1
    $\begingroup$ Oh my god, brockmann, thank you so much, you saved my life! It's working! I've ran the script, and the new button "Set UV Layer on all Objects in Selection" has appeared in the UV Maps (Properties Menu). And as documented in the manual, you can save your script in the scripts/startup/ directory with a .py extension and it will be automatically imported and ran on startup. $\endgroup$
    – Yan Kansky
    Apr 6, 2020 at 12:23
  • 1
    $\begingroup$ Cool! You're welcome, good and clear question btw. Suggest create an add-on out of the operator: How to create a custom UI? If you need help, just let me know @user34311 $\endgroup$
    – brockmann
    Apr 6, 2020 at 12:38
0
$\begingroup$

I needed this as well! I made it into a small plugin, that adds some small functionality on top of this for deleting a UV map / layer on multiple channels, setting it, creating and setting the active render layer map.

The addon is free, you can get it here:

https://gum.co/Batch_UV_Operations_Blender

enter image description here

enter image description here

$\endgroup$
1
  • $\begingroup$ Thank you for making that! You should put it on BlenderMarket so more people can find it, it's very useful. $\endgroup$
    – purgebs
    Jan 12 at 3:37

You must log in to answer this question.

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