0
$\begingroup$

New to Python / blender API here. Here is the process I'm attempting to script after having manually selected a material from the active object:

  • identify texture
  • find all other materials in scene using that same texture
  • replace with selected material.

update : found the solution, problem was about the API changes in Blender 2.8.

(original issue) I'm stuck at step 1: I can't find a way to tell the API: "please get me a pointer to the active material's texture".

Is this possible?

Thanks in advance,

$\endgroup$

1 Answer 1

0
$\begingroup$

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.')
$\endgroup$

You must log in to answer this question.

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