TLDR: You can create one material per polygon and assign all the materials using(strictly speaking: the respective index of each material slot) to MeshPolygon.material_index
.
I'd suggest create a dictionarycreate a dictionary based on the actual face id and the image path beforehand (//
prefix is a Blender specific identifier for the current blend file):
images_per_polygon = {
0: "city"//city.exr",
1: "courtyard"//courtyard.exr",
2: "forest.exr",
3: "interior.exr",
4: "night"//forest.exr",
5: "studio.exr"
...
}
Then iterate through all Mesh.polygons
, create a material based on the current index, create the relevantadd all nodes, load and assign the image to the Image Texture node using BlendDataImages.load()
and assign each material to the polygons properlyrespective face/polygon id to MeshPolygon.material_index
.
Demo on how to setup one image per polygon using the default cube and the built-in hdris based on How to load an image from disc and assign it to a newly created image texture node? and How can I get the filepaths of all default/built-in hdris?How to assign a new material to an object in the scene from Python? assuming the following folder structure (6 faces hence 6 images).(6 faces hence 6 images):
main_folder/
├── file.blend/
├── textures
├── city.exr
├── courtyard.exr
├── forest.exr
...
import bpy
# Get a reference to the object in context
# -> https://blender.stackexchange.com/a/239102/
obj = bpy.context.object
# Create the dictdictionary
# polygon id: "/path/to/current/blend/textures/image.exr"
images_per_polygon = {
0: "/Applications/Blender.app/Contents/Resources/2.93/datafiles/studiolights/worldtextures/city.exr",
1: "/Applications/Blender.app/Contents/Resources/2.93/datafiles/studiolights/worldtextures/courtyard.exr",
2: "/Applications/Blender.app/Contents/Resources/2.93/datafiles/studiolights/worldtextures/forest.exr",
3: "/Applications/Blender.app/Contents/Resources/2.93/datafiles/studiolights/worldtextures/interior.exr",
4: "/Applications/Blender.app/Contents/Resources/2.93/datafiles/studiolights/worldtextures/night.exr",
5: "/Applications/Blender.app/Contents/Resources/2.93/datafiles/studiolights/worldtextures/studio.exr"
}
# Remove all material slots from the object
# -> https://blender.stackexchange.com/a/146719/
obj.active_material_index = 0
for i in range(len(obj.material_slots)):
bpy.ops.object.material_slot_remove({'object': obj})
# Create (if not present) the materials and assign them per polygon
for c, p in enumerate(obj.data.polygons):
image = images_per_polygon.get(c)
if image:
# Create the material based on the name if not present
# -> https://blender.stackexchange.com/a/23434
mat_name = "Mat{}".format(c)
mat = bpy.data.materials.get(mat_name)
if not mat:
mat = bpy.data.materials.new(mat_name)
# Append the materials to the slots and assign each per polygon
obj.data.materials.append(mat)
p.material_index = c
# Material Properties
# -> https://blender.stackexchange.com/q/23436/31447
mat.use_nodes = True
nodes = mat.node_tree.nodes
nodes.clear()
# Create Principled Shader node
node_principled = nodes.new(type='ShaderNodeBsdfPrincipled')
node_principled.location = 0,0
# Create Image Texture node
# -> https://blender.stackexchange.com/a/201414
node_tex = nodes.new('ShaderNodeTexImage')
# Assign the image
node_tex.image = bpy.data.images.load(image)
node_tex.location = -400,0
# Create Output node
node_output = nodes.new(type='ShaderNodeOutputMaterial')
node_output.location = 400,0
# Link all nodes
links = mat.node_tree.links
link = links.new(node_tex.outputs["Color"], node_principled.inputs["Base Color"])
link = links.new(node_principled.outputs["BSDF"], node_output.inputs["Surface"])
- Mesh's material_index is an index into what?
- How to assign a material to a single face of a mesh using Python API
- How to load an image from disc and assign it to a newly created image texture node?
- How to assign a new material to an object in the scene from Python?
- Control Cycles/Eevee material nodes and material properties using python?
- Removing all material slots in one go
- How can I get the filepaths of all default/built-in hdris?