How can i load a material for assigning to one object by slecting when i use py code to do?

How can i load a material for assigning to one object by slecting when i use py code to do?

This is code:

This Python file uses the following encoding: utf-8

import rhinoscriptsyntax as rs
import Rhino
import scriptcontext

rs.Command("_RenderLoadMaterialFromFile C:\glass.rmtl")
mat = scriptcontext.doc.Materials.Find(self.MaterialTable, materialName=“glass”)

if mat:

obj = rs.GetObject()

if obj:

index = rs.ObjectMaterialIndex(obj)

if index==-1: index = rs.AddMaterialToObject(obj)

@robinyss,

below is one example which works without using material ids or indices, just by using the material name:

# -*- coding: utf-8 -*-
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs
    
def ApplyMaterialTest():
    ids = rs.GetObjects("Select objects", 8+16+32, True, True, True)
    if not ids: return 
    
    # define path to the material and its name with extension
    path = "D:\\Temp\\"
    name = "Red Plastic.rmtl"
    
    # load the material, surround path+name with quotes to prevent errors
    cmd = "_RenderLoadMaterialFromFile "
    rc = rs.Command(cmd + chr(34) + path + name + chr(34), False)
    if not rc: return
    
    # assign loaded material name (without extension) to selected objects
    cmd = "_RenderAssignMaterialToObjects "
    rc = rs.Command(cmd + chr(34) + name[0:-5] + chr(34), False)
    if not rc: print "Error assigning material"
    
if __name__=="__main__":
    ApplyMaterialTest()

Note that you get an error message dialog if the material does not exists and if multiple materials are present with the same name in the material editor, _RenderAssignMaterialToObjects prints an error to the command line and does not assign it.

@Alain, many of the material related methods are still missing in python rhinoscript syntax. Could you please add these to Rhino 6:

rs.IsMaterial()
rs.MaterialCount()
rs.MaterialId()
rs.MaterialIds()
rs.MaterialIndex()
rs.MaterialIndices()
rs.MaterialsByColor()
rs.MaterialsByName()

c.

2 Likes

Hi clement,
Thank you for your help.

@clement
Hi clement,
If the name to give material was duplication,there was more than one material to use this name to give material failure.
How do you do for the material of duplicating name?
can you use “_RenderRemoveUnusedMaterials” to remove the material of duplicating name before?

Hi Clement,

Probably not for 6.0 but I scheduled it for 6.x (6.1)

@robinyss,

to prevent that a material gets loaded if it is already found, you could check all material names first and put the _RenderLoadMaterialFromFile below a condition:

    # check if the material name is already present
    materials = [mat.Name for mat in scriptcontext.doc.Materials]
    
    if not name[0:-5] in materials:
        # load the material, surround path+name with quotes to prevent errors
        cmd = "_RenderLoadMaterialFromFile "
        rc = rs.Command(cmd + chr(34) + path + name + chr(34), False)
        if not rc: return
    else:
        print "material '{}' is loaded already".format(name[0:-5])

If you change this in the script above, the material which is loaded with the same name gets assigned. Does this help ?

c.

@Alain,

thanks. Looks like we`re getting closer to the sunrise :wink:

c.

@clement @Alain
Thank you for your help. Now it does working well.
Can I use ! -_RunPythonScript () for making a toolbar button?

this is the code:(but failed)

! -_RunPythonScript (
#coding=utf-8
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

def ApplyMaterialTest():
ids = rs.GetObjects(“Select objects”, 8+16+32, True, True, True)
if not ids: return

# define path to the material and its name with extension
path = "D:\\Temp\\"
name = "Red Plastic.rmtl"

 # check if the material name is already present
materials = [mat.Name for mat in scriptcontext.doc.Materials]

if not name[0:-5] in materials:
    # load the material, surround path+name with quotes to prevent errors
    cmd = "_RenderLoadMaterialFromFile "
    rc = rs.Command(cmd + chr(34) + path + name + chr(34), False)
    if not rc: return
else:
    print "material '{}' is loaded already".format(name[0:-5])

# assign loaded material name (without extension) to selected objects
cmd = "_RenderAssignMaterialToObjects "
rc = rs.Command(cmd + chr(34) + name[0:-5] + chr(34), False)
if not rc: print "Error assigning material"

if name==“main”:
ApplyMaterialTest()
)

@robinyss, try to paste below code to run it from a button:

! -_RunPythonScript (
# -*- coding: utf-8 -*-
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs
    
def ApplyMaterialTest():
    ids = rs.GetObjects("Select objects", 8+16+32, True, True, True)
    if not ids: return 
    path = "D:\\Temp\\"
    name = "Red Plastic.rmtl"

    materials = [mat.Name for mat in scriptcontext.doc.Materials]
    if not name[0:-5] in materials:
        cmd = "_RenderLoadMaterialFromFile "
        rc = rs.Command(cmd + chr(34) + path + name + chr(34), False)
        if not rc: return
    else:
        print "material '{}' is loaded already".format(name[0:-5])
    
    cmd = "_RenderAssignMaterialToObjects "
    rc = rs.Command(cmd + chr(34) + name[0:-5] + chr(34), False)
    if not rc: print "Error assigning material"
    
ApplyMaterialTest()
)

c.

OK,very well.
Thanks.