0
$\begingroup$

Suppose I have a directory structure like thus:

/Meshes/
/Meshes/Group One/
/Meshes/Group One/Some_Mesh.gltf
/Meshes/Group One/AnotherThing.gltf
/Meshes/Group Two/MoreMeshes.gltf
/Meshes/Group Two/AmazingMesh.gltf
/Meshes/Group Three/another_one.gltf
/Textures/
/Textures/Group One/
/Textures/Group One/Some_Mesh_diffuse.png
/Textures/Group One/Some_Mesh_specular.png
/Textures/Group One/Some_Mesh_normal.png
/Textures/Group One/AnotherThing_diffuse.png
(etc)

Assume I have a custom scene already created ready for render, and a material suitable for applying to the meshes.

Each mesh has multiple corresponding textures (such as diffuse, spec, normal).

How can I set up a batch import to iterate through the directories, import each mesh, apply the master material, load its relevant textures into the material nodes, and render?

$\endgroup$
1
  • $\begingroup$ Voting to close as question is not focused on one problem. You have also not demonstrated what you have tried and where exactly you got stuck. $\endgroup$ Mar 8, 2023 at 0:49

1 Answer 1

0
$\begingroup$

Here is an example. Edit the variables at the top to configure it, then run.

The renders will be placed next to the .gltf files (eg. Some_Mesh_render.png).

import bpy
import os


######## Edit these ##########

# Full path to the directory containing Meshes/Textures folders
root_dir = "/path/to/your/dir"

# Name of the master material
master_material_name = "Master Material"

# Name of the Image Texture node for the diffuse texture
diffuse_node_name = "Diffuse"

# Name of the Image Texture node for the specular texture
specular_node_name = "Specular"

# Name of the Image Texture node for the normal texture
normal_node_name = "Normal"

##############################


def do_gltf(gltf_path, render_path, diffuse_path, specular_path, normal_path):
    bpy.ops.import_scene.gltf(filepath=gltf_path)

    for ob in bpy.context.selected_objects:
        if ob.type == 'MESH':
            mat = bpy.data.materials[master_material_name].copy()

            # Place copy of master material in first material slot
            if ob.data.materials:
                ob.data.materials[0] = mat
            else:
                ob.data.materials.append(mat)

            # Swap in textures
            dif_img = bpy.data.images.load(diffuse_path)
            spe_img = bpy.data.images.load(specular_path)
            nor_img = bpy.data.images.load(normal_path)
            mat.node_tree.nodes[diffuse_node_name].image = dif_img
            mat.node_tree.nodes[specular_node_name].image = spe_img
            mat.node_tree.nodes[normal_node_name].image = nor_img

            # Render
            bpy.context.scene.render.filepath = render_path
            bpy.ops.render.render(write_still=1)

            break

    # Remove imported objects when done
    bpy.ops.object.delete()


mesh_dir = os.path.join(root_dir, "Meshes")
texture_dir = os.path.join(root_dir, "Textures")

for folder in os.listdir(mesh_dir):
    mesh_group_dir = os.path.join(mesh_dir, folder)
    texture_group_dir = os.path.join(texture_dir, folder)

    for f in os.listdir(mesh_group_dir):
        if not f.lower().endswith(".gltf") and not f.lower().endswith(".glb"):
            continue

        name = os.path.splitext(f)[0]
        do_gltf(
            gltf_path=     os.path.join(mesh_group_dir, f),
            render_path=   os.path.join(mesh_group_dir, f"{name}_render"),
            diffuse_path=  os.path.join(texture_group_dir, f"{name}_diffuse.png"),
            specular_path= os.path.join(texture_group_dir, f"{name}_specular.png"),
            normal_path=   os.path.join(texture_group_dir, f"{name}_normal.png"),
        )
$\endgroup$

You must log in to answer this question.

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