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$
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$

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.