2
$\begingroup$

Let's say I have lots of materials and objects and collections dynamically linked from other .blend files, how do I know which library is responsible for a specific material? I cannot find this information anywhere in the UI.

$\endgroup$
1
  • 3
    $\begingroup$ Hi :). The material dropdown in Shader Editor also lists linked materials with source paths i believe :). Can't check right now tho. $\endgroup$ Commented Oct 4, 2021 at 14:36

2 Answers 2

1
$\begingroup$

Here is a python script that accomplishes what you want, along with the bonus of naming every object that contains the material you are looking for. I've spelled out a couple of things that could have been elided, to make it clear what it is doing.

import bpy

def find_linked_materials(wanted_name):
    """ returns a list of (object, material, linked file) tuples for every material
        that matches the wanted name and comes from a library
    """
    linked_materials = []
    for obj in bpy.context.scene.objects:
         for slot in obj.material_slots:
            mat = slot.material
            if mat.name == wanted_name and mat.library:
                linked_materials.append((obj.name, wanted_name, mat.library.name))
    return linked_materials

if __name__ == '__main__':
    wanted_name = 'Carpaint Modified'
    l = find_linked_materials(wanted_name)
    for e in l:
        print('object %s contains material %s from file %s' % e)

This script defines a function find_linked_materials that searches every object in the scene for that object's materials.

When the script finds the name you've specified, as the name of a material it checks to see if the material comes from a library.

If it does come from a library the script adds an entry to a list, a tuple containing the object, material, and library names.

You can, of course, use the function in many ways. It could be part of an add-in where the wanted_name is taken from a user interface, or it could search for multiple names, or it could stop at as soon as it found the material once, et cetera.

The script file ends with code to test the function using a material name.

$\endgroup$
1
$\begingroup$

Material.name_full is the unique data-block ID name (displayed in the material dropdown) and Library.filepath returns the filepath to the linked blend file: https://docs.blender.org/api/current/bpy.types.Library.html#bpy.types.Library

import bpy

for mat in bpy.data.materials:
    if mat.library:
        # Unique data-block ID name, Path to the library .blend
        print(mat.name_full, mat.library.filepath) # mat.name

If you want this to look nice:

import bpy

h = ('Linked Material', 'Filepath')
d = [h] + [(i.name, i.library.filepath) for i in bpy.data.materials if i.library]

for i, d in enumerate(d):
    line = ''.join(str(x).ljust(20) for x in d)
    print(line)
    if i == 0:
        print('-' * len(line)*2)

Output snippet:

Linked Material   Filepath          
------------------------------------------------------------------
Material1         /Users/USER/Desktop/matlib3.blend
Material2         /Users/USER/Desktop/matlib2.blend
Material3         /Users/USER/Desktop/matlib1.blend
$\endgroup$

You must log in to answer this question.

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