By using Revit Python Shell (a similar approach to Dynamo), I’ve written the code below to iterate over all materials within the document. I grabbed the material named Béton, coulé sur place with the ID 183853, which I’m trying to use as a layer material in my new wall type. However, I’m encountering the following error related to the MaterialId."
import math
from Autodesk.Revit.DB import *
from System.Collections.Generic import IList, List
uidoc = __revit__.ActiveUIDocument
doc = uidoc.Document
t = Transaction(doc, 'create New wall type')
# getting the first wall type within the document
first_wall_type = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsElementType().FirstElement()
# looking for the material named "Béton, coulé sur place " in the document
mat_Ids = FilteredElementCollector(doc).OfClass(Material).ToElementIds()
for m in mat_Ids:
mat = doc.GetElement(m)
if mat.Name == "Béton, coulé sur place":
mid = m
c = 1/0.3048
# Starting transaction
t.Start()
voile_BA_15 = first_wall_type.Duplicate('voile-BA_15')
cs = voile_BA_15.GetCompoundStructure()
Thick_wall = 0.20*c
mat = doc.GetElement(mid)
cl = CompoundStructureLayer()
cl.Width = Thick_wall
cl.MaterialId = mat.Id
cs.SetLayeres.LIST[CompoundStructureLayer](cl)
voile_BA_15.SetCompoundStructure(cs)
t.Commit()
import clr
import sys
import System
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import specify namespace
from Autodesk.Revit.DB.Structure import *
#import net library
from System import Array
from System.Collections.Generic import List, IList, Dictionary
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.GeometryReferences)
#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)
t = Transaction(doc, 'create New wall type')
# getting the first wall type within the document
first_wall_type = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_Walls)\
.WhereElementIsElementType()\
.First(lambda x : x.GetCompoundStructure() is not None and x.GetCompoundStructure().GetLayers().Count == 1)
# looking for the material named "Béton, coulé sur place " in the document
mat = FilteredElementCollector(doc).OfClass(Material).First(lambda x : x.Name == "Béton, coulé sur place")
c = 1/0.3048
# Starting transaction
if True:
t.Start()
voile_BA_15 = first_wall_type.Duplicate('voile-BA_15')
cs = voile_BA_15.GetCompoundStructure()
Thick_wall = 0.20*c
for structLayer in cs.GetLayers():
cs.SetMaterialId(structLayer.LayerId, mat.Id)
structLayer.Width = Thick_wall
voile_BA_15.SetCompoundStructure(cs)
t.Commit()
OUT = voile_BA_15
I tested your script, but I got the following error, related to the line below:
However, I tested the same code in the Revit Python Shell, where I was able to access the level properties, but I received the following error in the RPS console related to this part of the code:
Exception : System.MissingMemberException: ‘NoneType’ object has no attribute ‘GetLayers’
for structLayer in cs.GetLayers():
cs.SetMaterialId(structLayer.LayerId, mat.Id)
structLayer.Width = Thick_wall
Effectively, after debugging the code I discovered that the first_wall_type is a curtain wall, which does not seem to have a CompoundStructureLayer . In this case, I need to apply a filter that selects only the Basic Wall kind, but I’m struggling with how to do that.
I tried this syntax for the filter, but it doesn’t work!
It’s hard for me to use this filtering method at the moment. However, I solved my issue another way, and finally, I got my code working and tested it by creating walls as shown in the image below: