Hi @rajeev,
This is going to get a little complicated. Part of the complication is due to historical reasons and the way the material system has evolved over the last decade or two. I’ll try to explain it as simply as possible.
First, when I said it’s best to avoid ON_Material I forgot that it’s actually unavoidable when you want to assign a render material to a ModelGeometryComponent. This is because such an assignment requires the objects to be connected together by the use of an ON_Material since  ModelGeometryComponent existed long before ON_RenderMaterial did and the attributes of the model component uses the component index of the ON_Material to identify the material.
The ON_Material is connected to the ON_RenderMaterial by setting two values: the unique ID of the ON_RenderMaterial and a plug-in ID. It’s necessary for the plug-in ID to be set to the ‘universal’ value (which is all 9s) because it doesn’t belong to any 3rd-party plug-in (it belongs to the RDK subsystem of Rhino). The ON_Material has a SetRdkMaterialInstanceId() method that sets the render material’s ID and a SetMaterialPlugInId() method that sets the plug-in ID.
In summary, ModelGeometryComponent attributes uses the material index of an ON_Material which in turn indicates which ON_RenderMaterial to use by specifying its unique ID.
Below is an example of how to create a new render material and assign it to the first ModelGeometryComponent in the model. First an ON_Material is added to the model, its values are set and then we just get the first ON_ModelGeometryComponent in the model and use its attributes to assign the material. The ON_Material is given an index of zero as I assume it’s the first one being added. You might need to modify that.
About the UUIDs: this conversation has highlighted an oversight. These UUIDs were originally defined in the RDK and have not been exposed to users of ‘plain’ OpenNURBS. I will need to fix that by moving them into opennurbs_render_content.h. For now, just use the UUIDs below. I will try to fix this in the next day or so.
bool CreateAndAssignMaterial(ONX_Model& model)
{
  // Create the render material, set its properties and add it to the model.
  ON_RenderMaterial render_mat;
  const ON_UUID uuidCustomMaterialType = { 0xba51c000, 0xba51, 0xc000,
              { 0xba, 0x51, 0xc0, 0xba, 0x51, 0xc0, 0x00, 0x00 } };
  render_mat.SetTypeId(uuidCustomMaterialType);
  render_mat.SetName(L"My Material");
  const ON_4fColor col(1.0f, 0.5f, 0.5f, 1.0f);
  render_mat.SetParameter(ON_MATERIAL_DIFFUSE, ON_XMLVariant(col));
  model.AddModelComponent(render_mat);
  // Create an ON_Material to use for the render material assignment and add it to the model.
  ON_Material mat;
  mat.SetIndex(0); // Assume first material.
  mat.SetRdkMaterialInstanceId(render_mat.Id());
  const ON_UUID uuidUniversal = { 0x99999999, 0x9999, 0x9999,
              { 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99 } };
  mat.SetMaterialPlugInId(uuidUniversal);
  model.AddModelComponent(mat);
  // Get the first ON_ModelGeometryComponent and get its attributes.
  ONX_ModelComponentIterator it(model, ON_ModelComponent::Type::ModelGeometry);
  const auto* mgc = ON_ModelGeometryComponent::Cast(it.FirstComponent());
  if (nullptr == mgc)
    return false; // No suitable component in the model.
  auto* attr = mgc->ExclusiveAttributes(); // Get attributes allowing modification.
  if (nullptr == attr)
    return false;
  // Set the material source to 'from object'.
  attr->SetMaterialSource(ON::material_from_object);
  // Set the material index to the index of the ON_Material.
  attr->m_material_index = mat.Index();
  return true;
}