Obtaining a list of all the materials

Dear Sir / Madame,

I’m trying to obtain a list of materials, but it seems that the list only contains those that are assigned to the objects in the scene. Is this correct behavior? And is there an alternative way to obtain a full list of materials.

The code I’m using is:
auto &materials = RhinoApp().ActiveDoc()->m_material_table;
RhinoApp().Print("MaterialCount(): %d\n", materials.MaterialCount());
RhinoApp().Print("Material #0: %s\n", get_name(materials[0]).c_str());

When I start with an empty scene with 2 materials, the list of materials is empty, as can be seen by querying the MaterialCount() property. Only after applying a material (in my case the second one) to an object, I can see that there is 1 material. However, that one is the second one, and not the first one in the list.

Kind regards,
Erik Valkering

You should use an ONX_ModelComponentIterator to iterate of the ONX_Model. Set it up with ON_ModelComponent::Type::RenderMaterial

Here a sample to iterate over instance definitions.

Thanks Nathan.

It is still unclear to me how to obtain an ONX_Model. All I have is the RhinoApp(). Does that provide this information?

Also, is there an ON_… corresponding to the ON_ModelComponent::Type::RenderMaterial (like ON_InstanceDefinition corresponds to ON_ModelComponent::Type::InstanceDefinition)?

Kind regards,
Erik

Hmm, not sure about that. @dale, can you help out here? Thanks.

This should do it:

CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
  EnumMaterialTable(context.m_doc);
  EnumRdkMaterialTable(context.m_doc);
  return CRhinoCommand::success;
}

void CCommandTest::EnumMaterialTable(CRhinoDoc& doc)
{
  const CRhinoMaterialTable& material_table = doc.m_material_table;
  int index = 0;
  for (int i = 0; i < material_table.MaterialCount(); i++)
  {
    const CRhinoMaterial& material = material_table[i];
    if (!material.IsDeleted())
    {
      ON_wString name = material.Name();
      RhinoApp().Print(L"Material(%d) = %s\n", index++, static_cast<const wchar_t*>(name));
    }
  }
}

void CCommandTest::EnumRdkMaterialTable(CRhinoDoc& doc)
{
  const CRhRdkDocument& rdk_doc = CRhRdkDocument::Get(doc);
  const IRhRdkContentList& material_list = rdk_doc.MaterialList();

  IRhRdkContentList::Iterator* iterator = material_list.NewIterator();
  if (nullptr == iterator)
    return;

  int index = 0;
  const CRhRdkContent* content = nullptr;
  while (nullptr != (content = iterator->Next()))
  {
    if (content->IsKind(CRhRdkContent::Kinds::Material))
    {
      const CRhRdkMaterial* material = static_cast<const CRhRdkMaterial*>(content);
      if (nullptr != material)
      {
        ON_wString name = material->InstanceName();
        RhinoApp().Print(L"RDK Material(%d) = %s\n", index++, static_cast<const wchar_t*>(name));
      }
    }
  }
}

– Dale