Create PBR and add to Rhino document

Hi,

I wanted to write an import helper for pbr-style-materials,

While i can create a PhysicallyBasedMaterial instance and set its texture channels vie the SetTexture() methods, I struggle on how exactly to add the material to the document.

Is there something already exposed inside of the WIP Rhinocommon?

Neither the MaterialTable nor the RenderMaterialTable seem to accept a PhysicallyBasedMaterial instance.

Are you loading the PBR from a specific file type? What exactly are you trying to do?

Hi @andy,
Thanks for getting back to me.

I’m writing an integration for an application which exports its PBR materials as JSON:
I get pbr materials as json Objects where the main types roughly are

  • Material: Contains list of Texture
  • Texture: Contains FilePath on disk of texture images and type of texture, e.g. albedo or ambient occlusion.

I want to build a rhino PhysicallyBasedMaterial from that information, inside a PlugIn, basically filling all the texture slots with the texture files and adding the generated Material to the Rhino Document.

This is probably the best way to do it:

      var pbr = RenderContentType.NewContentFromTypeId(ContentUuids.PhysicallyBasedMaterialType, doc) as RenderMaterial;

      var simTex = new SimulatedTexture;
      simTex.Filename = "my_base_color_texture.png";
      var baseTexture = RenderTexture.NewBitmapTexture(simTex, doc);

      simTex.Filename = "my_roughness_texture.png";
      var roughTexture = RenderTexture.NewBitmapTexture(simTex, doc);

      pbr.SetChild(baseTexture, RenderMaterial.PhysicallyBased.ChildSlotNames.BaseColor);
      pbr.SetChild(roughTexture, RenderMaterial.PhysicallyBased.ChildSlotNames.Roughness);

      doc.RenderMaterials.Add(pbr);

You might want to consider implementing a RenderContentSerializer instead of making a command line tool. That way, drag and drop will work automatically, and you will also be able to load your json files directly from the Import from Material Library function in the material editor.

Thanks again @andy,

I implemented your approach and it works!

Some additional thoughts, if someone else tries to implement something similar in the future:

  • you have to explicitly set the child slot as on or the initial result will look like nothing happened:
// add render texture as a child
pbr.SetChild(renderTexture, information.ChildSlotName);
pbr.SetChildSlotOn(information.ChildSlotName, true, RenderContent.ChangeContexts.Ignore);
  • I did not find an equally clean way of setting the render material to an object like with the normal Material and ended up doing something like this`:
// create sphere
var sphere = new Sphere(Plane.WorldXY, 2);

// add sphere to object table
var id = _doc.Objects.AddSphere(sphere);

// get sphere object
var sphereObject = new ObjRef(id).Object();

// Add material to document
AddRenderMaterial(material);

// assign material
sphereObject.Attributes.MaterialSource = ObjectMaterialSource.MaterialFromObject;
sphereObject.RenderMaterial = material;
sphereObject.CommitChanges();