MaterialTable.Find not working as expected?

When I try this

Rhino.DocObjects.Tables.MaterialTable.Find(material_name, True)

I get this

Find() takes exactly 3 arguments (2 given).

But documentation here specifies only two arguments. Am I doing something braujawnscably wrong?

Hi Bhupati,

this seems to work under windows:

import scriptcontext

def FindMaterialByName(mat_name):
    # find a material by name
    mat_table = scriptcontext.doc.Materials
    mat_index = mat_table.Find(mat_name, True)
    if mat_index >= 0:
        print("{0} found at index {1}").format(mat_name, mat_index)
    else:
        print("material named {} not found in table").format(mat_name)

if __name__=="__main__":
    FindMaterialByName("White Matte")

c.

Thanks! @clement. I guess the problem is with the Rhino library function. Maybe @dale has some inputs on that?

Also, I will be stuck when I go in to translate my current Python project to VB Script.

The error message may be a bit confusing, but it is correct. Find is a member function of the material table (as opposed to a static function) which means you need an instance of the table class in order to call the function.

doc.Materials will give you the instance of the table that you can call Find on as @clement showed in his sample. An alternate form of the same thing that you can call in python is to pass the instance as the first parameter. So

Rhino.DocObjects.Tables.MaterialTable.Find(doc.Materials,name,True)

Is equivalent to

doc.Materials.Find(name,True)

1 Like

Thanks, @stevebaer! That makes sense.

Very useful explanation of the error, thanks. For me, the above works only if the material is used in the doc (on an object or layer).

Is it possible to search by name for unused materials? From looking around I came across scriptcontext.doc.RenderMaterials…

But there’s no Find function. I have resorted to a “for X in sc.doc.RenderMaterials” loop and assigning each rendermaterial to a point in an invisible layer (with scriptcontext.doc.Objects.ModifyRenderMaterial). Since the materials are now used, I then search in the material table as above. Perhaps there is a less hacky way?

I experimented also with Rhino.DocObject.RenderMaterial and Rhino.Render.RenderMaterialTable… Also tried to assign to layers with Rhino.DocObjects.Layer.RenderMaterial or scriptcontext.doc.Layers… Couldn’t figure out anything useful.

The Material.UseCount property returns the number of objects and layers that use the material.

Does this help?

Hi @dale,

i’ve tried this too but without result. For a Rhino.Render.RenderMaterial the UseCount seems not to be available and for regular materials if a single material is assigned twice, the material is listed twice (one time for every assignment) and UseCount is always 1.

Tested this in V5 only…

c.

This is still true in v6 in my experience.