Blender Python: select the imported object and plug a texture into a Cycles node

Hello everyone!

I am quite new to scripting in Blender, and I have been searching everywhere I could for the answer to my question. Here’s the thing.

I am working on a script that imports a list of .obj and exports them into GLTF. Basically, for each imported object, I want to import the texture attached to it into the node editor, as well as some other textures that are currently not attached to the obj. Then I want to connect all these textures into the right places on the GLTF roughness/metallic node, and basically export the object in GLTF.

I am good with the importing of the objects, but now I have two problems:

  • Once the object imported, I don’t know how to select it to add a material. Here’s the code for that part:
import bpy
import os
import math
import shutil
import glob
 
# put the location to the folder where the objs are located here in this fashion
# this line will only work on windows ie C:\objects
filepath= os.path.join('C:\\', 'Users', 'mae_l', 'Desktop', 'Conversion_Test')
 
filename=os.path.basename(filepath)

# get list of all files in directory
folder_list = sorted(os.listdir(filepath))

obj_list=[]
tex_list=[]

#for item in folder_list:
obj_list.extend(glob.glob('c:\\users\\mae_l\\desktop\\conversion_test\\*\\*.obj'))
obj_list.extend(glob.glob('c:\\users\\mae_l\\desktop\\conversion_test\\*\\*\\*.obj'))
obj_list.extend(glob.glob('c:\\users\\mae_l\\desktop\\conversion_test\\*\\*\\*\\*.obj'))

tex_list.extend(glob.glob('c:\\users\\mae_l\\desktop\\conversion_test\\*\\*.jpg'))
tex_list.extend(glob.glob('c:\\users\\mae_l\\desktop\\conversion_test\\*\\*.jpeg'))
tex_list.extend(glob.glob('c:\\users\\mae_l\\desktop\\conversion_test\\*\\*.png'))

tex_list.extend(glob.glob('c:\\users\\mae_l\\desktop\\conversion_test\\*\\*\\*.jpg'))
tex_list.extend(glob.glob('c:\\users\\mae_l\\desktop\\conversion_test\\*\\*\\*\\*.jpeg'))
tex_list.extend(glob.glob('c:\\users\\mae_l\\desktop\\conversion_test\\*\\*\\*\\*.png'))
    
print(tex_list)

for item in obj_list:
                   
    path_to_file = os.path.join(filepath, obj_list[0]) #attention remplacer par item
    bpy.ops.import_scene.obj(filepath = path_to_file)
    ob= bpy.context.scene.objects.active
    

    for item in tex_list:
        tex=item
        mat = bpy.data.materials.new(name='mat')
        mat.use_nodes=True
        ob.data.materials.append(mat)
        matnodes = mat.node_tree.nodes
        diff_texture=matnodes.new("ShaderNodeTexImage")
  • Second problem: I can’t import the image into the node editor, and I guess it must be a context problem, but I have tried many “context_override” codes and I still can’t figure how that works. Here is a little test I have tried besides the global code:
import os, bpy

filepath= os.path.join('C:\\', 'Users', 'mae_l', 'Desktop', 'Conversion_Test', 'Science-Technology', '105_CNC-milling-machine','105_CNC-milling-machine_Diff_2048.jpg')

for window in bpy.context.window_manager.windows:
    screen = window.screen
    
    for area in screen.areas:
        #print(area.type)
        if area.type == 'VIEW_3D':
            for space in area.spaces:
                if space.type == 'VIEW_3D':
                    rv3d = bpy.context.region
                    override = {'window': window, 'screen': screen, 'area': area, 'region': rv3d}
            
Cube=bpy.ops.mesh.primitive_cube_add()
ob=bpy.context.active_object
mat = bpy.data.materials.new(name='mat')
mat.use_nodes=True
ob.data.materials.append(mat)
matnodes = mat.node_tree.nodes


diff_texture=matnodes.new("ShaderNodeTexImage")

bpy.context.window_manager.windows[0].screen.areas[0].type = 'NODE_EDITOR'
bpy.ops.node.add_file(override, 'EXEC_DEFAULT', filepath=filepath)

As you can see, I think I’m mixing a lot of things without understanding them, and so I’m really lost. Can someone help me figure this mess out?

Thank you so much,

Maybe this will help some.

selecting objects

import bpy


scn = bpy.context.scene

#Get all scene objects
for scn_objs in scn.objects:
	#Check to see if object type is mesh
	if scn_objs.type == 'MESH':
		#Select all mesh objects
		scn_objs.select = True
	else:
		scn_objs.select = False 

loading image

import os, bpy


filepath= os.path.join('C:\\', 'Users', 'mae_l', 'Desktop', 'Conversion_Test', 'Science-Technology', '105_CNC-milling-machine','105_CNC-milling-machine_Diff_2048.jpg')


#Load image into Blender			
loaded_image = bpy.data.images.load(filepath)


ob = bpy.context.active_object
mat = bpy.data.materials.new(name='mat')
mat.use_nodes=True
ob.data.materials.append(mat)

matnodes = mat.node_tree.nodes


diff_texture_node = matnodes.new("ShaderNodeTexImage")
#Assign the loaded image to the diffuse texture node
diff_texture_node.image = loaded_image

Hey !
Thank you for your answer! So until now I had only time to try your first script, and it didn’t work at first, because the problem was that the object was selected (orange outline) but not ACTIVE (yellow outline), and thus I couldn’t operate on it later on. So I started with your script and I had to force the object to be active, like this:

my_scene = bpy.context.scene
for this_object in ma_scene.objects:
	if this_object.type == 'MESH':

		bpy.context.scene.objects.active = this_object

curr_object = bpy.context.active_object

And it worked. I’m going to try your suggestion about the texture and I’ll keep you posted :slight_smile:

Thank you very much!

Ok it works, thank you! Now I have another problem about getting the GLTF Metallic Roughness group in Python, but it should be another topic. I’m going to write it now. Thank you again!