Material, Physical and Thermal Assets

Today, we concentrate fully on material, physical and thermal assets:

Issues Accessing and Creating Material Assets

Quite a number of issues were discussed in the past few months involving issues accessing and creating material assets.

As far as I know, they can all be solved, cf. below.

Sometimes, though, the access is slightly convoluted and confusing.

Here is an overview over some recent issues:

Older discussions are listed in the topic groups on material management and libraries and texture bitmap and UV coordinate access.

Access to All Material Asset Properties

I am very glad to announce that my colleagues Liz Fortune and Balaji Arunachalam confirm that they can access each and every parameter of the materials, appearance assets, thermal assets, and physical assets (with one single exception, cf. below):

Balaji and I have been able to access each and every parameter of the material, appearance asset, thermal asset, and physical asset EXCEPT for the keywords parameter that lives on the Identity tab of the Material UI in Revit. We can connect to the keywords for all of the assets above but would like to also connect to the keywords that live on the material itself.

To access this data, we used code snippets shared on The Building Coder blog to implement the following:

void GetElementMaterialInfo( Document doc )
{
  FilteredElementCollector collector
    = new FilteredElementCollector( doc )
      .WhereElementIsNotElementType()
      .OfClass( typeofMaterial ) );

  try
  {
    foreachMaterial material in collector )
    {
      if( material.Name.Equals( "Air" ) )
      {
        AppearanceAssetElement appearanceElement
          = doc.GetElement( material.AppearanceAssetId )
            as AppearanceAssetElement;

        Asset appearanceAsset = appearanceElement
          .GetRenderingAsset();

        List<AssetProperty> assetProperties
          = new List<AssetProperty>();

        PropertySetElement physicalPropSet
          = doc.GetElement( material.StructuralAssetId )
            as PropertySetElement;

        PropertySetElement thermalPropSet
          = doc.GetElement( material.ThermalAssetId )
            as PropertySetElement;

        ThermalAsset thermalAsset = thermalPropSet
          .GetThermalAsset();

        StructuralAsset physicalAsset = physicalPropSet
          .GetStructuralAsset();

        ICollection<Parameter> physicalParameters
          = physicalPropSet.GetOrderedParameters();

        ICollection<Parameter> thermalParameters
          = thermalPropSet.GetOrderedParameters();

        // Appearance Asset

        forint i = 0; i < appearanceAsset.Size; i++ )
        {
          AssetProperty property = appearanceAsset[ i ];
          assetProperties.Add( property );
        }
        foreachAssetProperty assetProp in assetProperties )
        {
          Type type = assetProp.GetType();
          object assetPropValue = null;
          var prop = type.GetProperty( "Value" );
          if( prop != null
            && prop.GetIndexParameters().Length == 0 )
          {
            assetPropValue = prop.GetValue( assetProp );
          }
        }

        // Physical (Structural) Asset

        foreachParameter p in physicalParameters )
        {
          // Work with parameters here
          // The only parameter not in the orderedParameters 
          // that is needed is the Asset name, which you 
          // can get by 'physicalAsset.Name'.
        }

        // Thermal Asset

        foreachParameter p in thermalParameters )
        {
          // Work with parameters here
          // The only parameter not in the orderedParameters 
          // that is needed is the Asset name, shich you 
          // can get by 'thermalAsset.Name'.
        }
      }
    }
  }
  catchException e )
  {
    Console.WriteLine( e.ToString() );
  }
}

This code will get you everything for the thermal and structural assets and almost everything for the appearance asset.

Boris Shafiro's PDF from his AU presentation on modifying material visual appearance was crucial in figuring out how to touch all the aspects of the appearance asset!

Here is an image I put together showing mappings for the appearance asset:

Air appearance properties

The spreadsheet in this image was created from output of my code into a CSV. Hope this helps.

Many thanks to Liz and Balaji for their research and sharing the results!

No Access to Material Keywords

As mentioned above, one single property is apparently still not accessible: the keywords parameter that lives on the Identity tab of the Material UI in Revit.

Apparently, the internal property Material.getKeywords is not exposed to the official Revit API, and there is no built-in parameter for it either.

Access to Environment and Render Settings

We also searched for the Environment and Render Settings values. They are common for all the Assets:

Environment assets

Environment assets

Render settings

Render settings

They are common for all assets, so they look like the other properties or parameters, but are in fact part of the UI config and saved into MaterialUIConfig.xml.

Determine Full Path to Texture Bitmap

Finally, to round off this collection, here is a result from a comment on material asset textures:

Question: Great tip, but how can we create the full path to the unifiedbitmap_Bitmap texture? I tried using the Application GetLibraryPaths method, but the material library is not listed in the dictionary.   :(

Answer: If all else fails, you can try to use the operating system functionality to search globally for the given filename. You should cache the folders in which you find it. If the system is sensibly set up, you will only need to search for it globally once, or a very few times, since there should not be many different locations in which these files are stored.

Response: Thank you for this tip, especially for the cache recommendation.

Works like a charm.   :)

Addendum – Modifying Material Assets

Question: Can you also confirm that you can create new materials and successfully populate all these properties as well?

Answer: I have successfully modified the values for the parameters.

I attempted a handful.

The trick I found was that I needed to identify the storage type of each so I could set the parameter accordingly.