Getting material from RhinoObject

I have two RhinoObjects and want to check if they share the same material (as seen in the UI). I’ve checked that the material is the same by right-clicking on the material in the UI and clicking “Select Objects”. I’m a little confused by the materials I get back here:

// rhinoObject0 and rhinoObject1 share a material in the UI.
var mat0 = rhinoObject0.GetMaterial(true);
var mat1 = rhinoObject1.GetMaterial(true);
Console.WriteLine(mat0.Id == mat1.Id) // this is false
Console.WriteLine(mat0.MaterialIndex == mat1.MaterialIndex) // this is also false

How do I get to the “shared” material I see in the UI?

The material index refers to the slot in the material table of the document. Unfortunately this table is set up such that each object and usage gets its own slot in the material table. So even if you have only one material added in the Materials panel, but you have assigned it to three objects you’ll see that the materials table has three entries. Each material is the same, just different index.

Instead of getting the Material I suggest you use the RenderMaterial you can get from RhinoObjects with the rhinoObject.RenderMaterial property. You can then use its Id to check for equivalence. These RenderMaterials correspond to what you see in the GUI.

1 Like

Thanks Nathan!
I always get lost in the words when dealing with materials in :rhinoceros: :slightly_smiling_face:

Ah wait… I’m still confused.

RenderMaterial doesn’t have the IsPhysicallyBased and PhysicallyBased property.
Instead of PhysicallyBased I can probably use this. Is there an equivalent to IsPhysicallyBased for RenderMaterials?

For RhinoCycles integration I use the following three lines to ensure proper Physically Based material:

pbrmat will be a Rhino.DocObjects.PhysicallyBasedMaterial, but I prefer the rmFromPbrMat to query for the RenderTextures, since that will give you also access to the amount of a texture.

The above three lines may seem like a round-about way to get to the Physically Based material, but it will ensure you get proper access to third-party materials that implement a PBR material derived from RenderMaterial. These steps handle the simulation etc for you.

2 Likes

Thanks! I’ll have to grog it later.

But I think this is a very fine example of why I’m confused about Material vs RenderMaterial:

  1. I have a Material.
  2. I need to switch to a RenderMaterial.
  3. So I can query for a Material?? :laughing:

Actually, a Rhino.DocObjects.PhysicallyBasedMaterial is not a Rhino.DocObjects.Material :stuck_out_tongue:

Anyway, the Rhino.DocObjects.Material is the old material format. I prefer the new Rhino.Render.RenderMaterial format, since it is more modern. The Rhino.DocObjects.PhysicallyBasedMaterial is a strictly-typed version of the physically based material supported by Rhino 7 and later, but using Rhino.Render.RenderMaterial.FromMaterial(Rhino.DocObjects.PhysicallyBasedMaterial.Material) will give you the Rhino.Render.RenderMaterial through which you can access RenderTextures (along with all other parameters, which you can get at with .GetParameter().

But you’re right, this all isn’t straightforward, nor easy to understand. I suppose after holidays we should write some good overview of how materials work in Rhino. It is a bit of a mess.

2 Likes