1
$\begingroup$

I'm currently working on porting a section of a world/map from one game to use in source filmmaker. I've managed to import the section I wanted and I'm stuck at a very slow and repetitive process.

What I have is dozens of objects (which I imported directly from my game), the material names were assigned based on the name of the object and the texture was set accordingly.

So lets say an object I imported is called chair, and this object has 3 materials or so. Each material will be named chair.001, chair.002, chair.003, etc etc. Now, the texture files/images are named correctly, lets say the textures are named chairwood chairclooth chairmetal or something of that sort. What I need is to be able to automatically merge the names of the materials with the textures they are assigned, so whatever the filename is the material is automatically changed to it. Several of the objects I have use the same texture file whilst having differently named materials, so you can see why its a royal pain.

Pretty much I need to know if I can do any of the following things with or or without existing addons/scripts or default tools in blender. 1) Can you select/batch multiple materials and rename them to all have the same name? 2) Convert/export textures to have them the same as the material?

I've included a imgur link of what I'm trying to explain, maybe it'll be easier to understand what I'm getting at https://i.stack.imgur.com/Dm86q.png

$\endgroup$
0

2 Answers 2

1
$\begingroup$

Using blender internal, the textures can be found in bpy.data.textures. By looping through this you can easily match the texture name to the image it has.

import bpy

for tex in bpy.data.textures:
    if tex.type == 'IMAGE':
        tex.name = tex.image.name

Usually the image name is its filename without extension, if you have image names with extensions, you can use os.path.splitext to remove the extension.

tex.name = os.path.splitext(tex.image.name)[0]
$\endgroup$
3
  • $\begingroup$ Not entirely sure what you mean. The code you have provided me, is this something I can just copy paste into text editor and run or is it just a example? I’m still relatively new to Blender so I haven’t picked up on the name of each tool/section/options it has, mainly learned stuff through testing things out. How would I access blender internal, is that some sort of script/text file editable within blender? Forgive me if I sound stupid lol, this is my first time making a help thread on Blender. $\endgroup$
    – DrJoseEvil
    Nov 13, 2018 at 14:42
  • $\begingroup$ @DrJoseEvil Blender internal is the render engine, the way your textures show in the outliner means that is what your materials are setup for. The above script should just do what you want as it is, paste it into blenders text editor and run it, then check things look right before saving. $\endgroup$
    – sambler
    Nov 13, 2018 at 20:52
  • $\begingroup$ The script is giving me a error On line 5 AttributeError: 'NoneType' object has no attribute 'name' Error: Python script fail, look in the console for now... $\endgroup$
    – DrJoseEvil
    Nov 14, 2018 at 23:03
0
$\begingroup$

Select your desired object and copy and past the script to the console, hit enter twice and your good to go.

import bpy
import os
# Set the material_index to 0 ( the first material )
bpy.context.object.active_material_index = 0
# Go through list of materials assigned to selected object
for material in bpy.context.object.data.materials:
    material_index = bpy.context.object.active_material_index
    old_name = material.name
    try:
        # Get its first material slot
        material = bpy.context.active_object.material_slots[material_index].material
        # Get the nodes in the node tree
        nodes = material.node_tree.nodes
        # Get a principled node
        principled = next(n for n in nodes if n.type == 'BSDF_PRINCIPLED')
        # Get the slot for 'base color'
        base_color = principled.inputs['Base Color'] #Or principled.inputs[0]
        # Get the link
        link = base_color.links[0]
        link_node = link.from_node
        # Rename the material to the image name excluding the extension
        material.name = os.path.splitext( link_node.image.name )[0]
        # Print the results
        print( "Material Old Name:", old_name, )
        print( "Material New Name:", material.name )
        print( )
    except:
        print( 'not found' )
    # Add 1 to the material_index count ( move to the next material )
    bpy.context.object.active_material_index +=1

Source: https://blenderartists.org/t/batch-rename-materials-with-file-names-of-linked-texture/1215110/5

$\endgroup$
1
  • $\begingroup$ Recommend pasting into and running scripts from text editor. _Having blank lines where indented will cause an error in blender's py console _ $\endgroup$
    – batFINGER
    Mar 25, 2020 at 1:19

You must log in to answer this question.

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