Run the script, select your images and you will have Rhino Materials, named, and with the images assigned as textures in one second!
#! python 3
# -*- coding: utf-8 -*-
import Rhino
import scriptcontext as sc
import os
# CREATE MATERIALS FROM IMAGES
# Work on the active Rhino document
doc = Rhino.RhinoDoc.ActiveDoc
sc.doc = doc
def get_image_files():
"""
Opens a multi-select file dialog for image files.
Returns a list of full file paths (or empty list if cancelled).
"""
dlg = Rhino.UI.OpenFileDialog()
dlg.Title = "Select image files for materials"
dlg.Filter = (
"Image Files (*.jpg;*.jpeg;*.png;*.bmp;*.tif;*.tiff)|"
"*.jpg;*.jpeg;*.png;*.bmp;*.tif;*.tiff|"
"All files (*.*)|*.*||"
)
dlg.MultiSelect = True
if not dlg.ShowOpenDialog():
return []
try:
return list(dlg.FileNames)
except:
if dlg.FileName:
return [dlg.FileName]
return []
def material_name_exists(name):
"""
Check if a material with this name already exists
either as a RenderMaterial or a legacy Material.
"""
# Check RenderMaterials (what the Material Editor shows)
for rm in doc.RenderMaterials:
if rm.Name == name:
return True
# Also check legacy materials, in case there are old ones around
if doc.Materials.Find(name, True) != -1:
return True
return False
def get_unique_material_name(base_name):
"""
If base_name exists, returns 'base_name (1)', 'base_name (2)', etc.
"""
if not material_name_exists(base_name):
return base_name
counter = 1
while True:
candidate = "{} ({})".format(base_name, counter)
if not material_name_exists(candidate):
return candidate
counter += 1
def create_render_material_from_image(image_path):
"""
Creates a RenderMaterial with the image as its color texture
and adds it to doc.RenderMaterials so it shows up in Material Editor.
Returns the final material name.
"""
# Use file name (without extension) as base material name
base_name = os.path.splitext(os.path.basename(image_path))[0]
mat_name = get_unique_material_name(base_name)
# 1) Create a *temporary* Rhino material (NOT added to doc.Materials)
rhino_material = Rhino.DocObjects.Material()
rhino_material.Name = mat_name
tex = Rhino.DocObjects.Texture()
tex.FileName = image_path
# Use the bitmap slot – CreateBasicMaterial will turn this into a render material
rhino_material.SetTexture(tex, Rhino.DocObjects.TextureType.Bitmap)
# 2) Create a basic RenderMaterial from the Rhino material
render_material = Rhino.Render.RenderMaterial.CreateBasicMaterial(rhino_material, doc)
render_material.Name = mat_name # ensure name is set
# 3) Add to RenderMaterials table (this is what the Material Editor displays)
doc.RenderMaterials.Add(render_material)
return mat_name
def main():
image_files = get_image_files()
if not image_files:
print("No files selected. Script cancelled.")
return
created = []
print("Selected images:")
for img in image_files:
print(" - {}".format(img))
print("")
for img in image_files:
try:
mat_name = create_render_material_from_image(img)
created.append(mat_name)
print('Created RenderMaterial: "{}" from "{}"'.format(mat_name, img))
except Exception as e:
print('Failed to create material from "{}": {}'.format(img, e))
if created:
print("\nSummary of created materials (RenderMaterials in active document):")
for name in created:
print(" - {}".format(name))
else:
print("No materials were created.")
doc.Views.Redraw()
if __name__ == "__main__":
main()
Quick tip. To run the script with an alias just add a command macro:
-RunPythonScript (C:\RhinoPythonScripts\MATfromIMG.py)
This script uses the Custom material type because this type has the most clear UI.