I asked ChatGPT to make materials from images

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.

1 Like