It’s been a while since the last time that I was looking at Materials in Dynamo. Literally more than 5 years. Here’s the last write up I did on that subject: Materials Guess what? Revit APIs don’t change…or so I thought. Well, let’s not give Revit developers too much credit here, but I was a little surprised to see that some things were added to the Revit API around Materials. Some are just weird, but for the most part it moved in the positive direction.
Anyways, so I was asked to pull together an example of how would one use Dynamo to create Materials in Revit from something like an Excel spreadsheet. Mhmmmmm. You could probably do this already back in the days, by simply making copies of the Material, but now we have a spanking new API, that allows us to “create” new Materials. Well, it’s not that new, but 2018+ versions of Revit have it so I was happy. Great. I wanted to set some properties on said Materials. Can I do that too? Yes, now we have APIs for creating new AppearanceAssetElements. Damn! Autodesk, what have gotten into you guys. OK, last one. What if I wanted to set the Rendering Appearance Asset so that I can use the fancy rendering properties like Reflectivity or Bump? Can I do that? Nope. For that one you still have to copy an existing AppearanceAssetElement. To be precise the AppearanceAssetElement is not an issue. There is an API to create one, but in order to control its Rendering Asset properties, we need to create an Asset, and that’s not something we can do. Back to duplicating existing objects. I guess I should have expected that. Thanks Autodesk.
Here’s the script as put together:
In order to create this script I ended up creating quite a few new components that were added to archi-lab.net package. Here’s a few comments about that:
- Materials.Create – this creates a new empty Material. All we need to create a new Material is a name – preferable unique.
- Materials.UseRenderAppearanceForShading – this is needed for us to override a default value. Revit doesn’t normally use Render Appearance Asset for shading, and when it’s disabled, in version 2018, for example it doesn’t even create the AppearanceAssetElement for it. It only gets created when we turn this on.
- AppearanceAssets.CreateViaDuplicate – this is the most important node in this script. Everything hinges on this node being able to find a “Default” Material. Every Revit file should have a material named Default, but just in case yours doesn’t please make sure to add one before using this node. I know I suck. Now, that I am thinking about this, I should have exposed an input for this. Ahhh…next time. Here’s the code for reference:
As you can see above the code is a little hacky, that’s why I wanted to share this. So in order to duplicate an AppearanceAssetElement we need a new name for object that would result from such operation. It has to be unique too, and since there is no static utility anywhere to check if proposed name is unique, we have to do a little try/catch inside of a while loop, or use the “goto”. I haven’t used a goto in a while so here we are.
- AppearanceAssets.SetGenericProperties – this node allows you to set color, glossiness, and whether a material is metallic or not. It comes from these properties in Revit:
There is a little cool thing worth knowing about setting Asset properties. Yes, Revit doesn’t exactly make that straight forward. First, the properties on an asset are stored in an array. They have some fancy names, and special types for setting them. Here’s how to obtain the value for Color for example:
Revit Lookup to the rescue. There is no good way to find out what we are looking for. I just had to look through these property arrays to sort out that Color is stored under DoubleArray4d. It’s name is really “generic_diffuse”. Once you have that info you can run the following code to set that info on an Asset:
Other properties that we are setting here like “glossiness” is also not very straight forward because in UI Glossiness is defined as a value between 0-100. That would normally suggest that we are dealing with an integer. Couldn’t be further from truth. Glossiness is actually stored as a double, remapped from 0-100 range into 0-1. It’s pretty simple, just divide by 100, but still…why?
- Materials.SetAppearanceAsset – nothing special here. We can use that node to set the AppearanceAssetElement on our newly created Material.
- Materials.SetMaterialClass – just a string value that we can use to categorize our materials.
- Materials.SetSurfacePattern – this sets the Surface Pattern. One trick here, is that the Fill Pattern that we want to use kind of has to exist in the model, unless we want to go into a whole new can of worms around creating Fill Patterns. If we assume that the Fill Pattern exists then we can just find it by its name. I added a few utility nodes for that.
- FillPatterns.Exists – returns true if Fill Pattern with a given name exists otherwise false.
- FillPattern.GetByName – returns a Fill Pattern with the given name.
When it comes to Fill Patterns please be aware that Revit 2018 will ship with a different set of them pre-loaded than let’s say Revit 2021. Just FYI. If your intent is to create Materials from an Excel spread sheet, you might have to keep a different version of the Excel for different versions of Revit.
Another gotcha moment that I already mentioned was that when you make a new model in Revit 2018, it will have some default Materials loaded into it. None of these Materials uses Rendering Appearance Assets, and hence none of them are created in the file. It’s weird, but basically you have to make sure that it exists first before trying to use one to create a duplicate of it.
Other than, that it looks like there were some improvements to the Revit API in the recent years. I definitely appreciate that as a developer. Could they have been better? Yes, it feels like the API around Materials is still not complete, and lacks crucial functionality especially for dealing with Assets. There is literally nothing in the API for Asset class. That’s a downer. Overall, with a little stretching, one can accomplish some basic tasks around Materials, so it’s all good.
Please let me know if you have any comments.
Thanks to Oliver Green we now have a complete reference of Asset property names to use with out scripts. One thing worth mentioning is that at the moment, I only exposed a handful of them via nodes in Dynamo, so unfortunately the full list is a great reference for those willing to jump in and get their hands dirty with some coding. It will not be very helpful for Dynamo users at the moment. If I am ever looking into Materials again, I might jump in there and include a few more of these. Don’t hold your breath here though. Either way, Oliver, thanks for sharing!
Hi there! I’m creating a library of materials out of an Excel Spreadsheet. In this spreadsheet I have all the configuration that I need to create my materials: graphics settings (foreground color, pattern, etc) all the identity data and so on, but I would like to create the materials with an Appereance Asset from the Library that already exists in Revit.
With my script I can create new Appereance Assets via duplicate, as you can see in the picture, but I would like to read the existing Appereance Assets from one of the Asset Browser and, kind of, “set parameter by name” to assign the correct one to each material. The problem is that this only work if the Appereance Asset alredy exists in the document, which isn’t ideal. Do you have any idea how can I query or collect the Appereance Assets from the Asset Browser?
I would probably need to see the actual files and try them out on my end to see if I can remedy this. I do offer consulting services so feel free to reach out to me at email@example.com Cheers!
Hi Konrad! I missed your answer, it is kind of overwhelming the amount of emails I get in my inbox.
We still working into development, talked to Scott and Jappy at McNeel, I still need to give it a serious try, but my idea seems to work for my goal, but it would be nice to share and discuss ideas, process and learnings with you. I’ll try to attend the AEC Tech conference in November.
Thanks for Clarifying the what the options really mean in terms of Revit APi.
i find the “Material Preview Scene” to have different types applied to different material in my file.. and hope change all to a standard scene. is there away to change that parameter too. Your annotations in red already helped to point to where i should do my search. just need a name! haha!