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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.