Ok, the following script does a bit more. See comments - disable "renameUVMaps" if you don't plan to join the meshes. Useful to rename the UV of identical textures so that mapping data is kept active.
import bpy
# Options
renameUVMaps = 1
# 1. Get the "active texture name"
activeObject = bpy.context.object
activeUVMap = activeObject.data.uv_layers[0]
activeMaterial = activeObject.active_material
activeTexture = activeMaterial.node_tree.nodes["Image Texture"]
targetImageFilename = activeTexture.image.name
print('Material %(materialName)s will now replace materials using texture %(textureName)s' % { 'textureName' : targetImageFilename, 'materialName' : activeMaterial.name})
# 2. Loop through scene objects and replace materials with the selected one (when the texture file name matches)
for obj in bpy.context.scene.objects :
# 2.1 Re-assign material
for slot in obj.material_slots :
thatMaterial = slot.material
thatTexture = thatMaterial.node_tree.nodes["Image Texture"]
thatImageFilename = thatTexture.image.name
if targetImageFilename == thatImageFilename :
if activeMaterial != thatMaterial :
print('Obj %(objName)s -> replacing %(materialName)s in slot' % { 'objName' : obj.name, 'materialName' : thatMaterial.name })
slot.material = activeMaterial
# 2.2 Rename UV Maps for joining
if renameUVMaps == 1 :
if hasattr(obj.data, 'uv_layers'):
layers = obj.data.uv_layers
layerCount = len(layers)
if layerCount > 1 :
print('!!! Obj %(objName)s -> has more than 1 UV layer' % { 'objName' : obj.name })
if layerCount == 1 :
uvLayer = layers[0]
if uvLayer.name != activeUVMap.name :
print('Obj %(objName)s -> renaming UV layer to %(targetUVMapName)s (was %(previousName)s)' % { 'objName' : obj.name, 'targetUVMapName' : activeUVMap.name, 'previousName' : uvLayer.name })
uvLayer.name = activeUVMap.name
print('Done.')