Exception: System.IndexOutOfRangeException: index out of range: 0
when trying to get the single material in my list called material. I used the usual syntax mat = material[0] to get this material from the list, but it doesn’t seem to be working!!?
Here my code:
import math
from Autodesk.Revit.DB import *
from System.Collections.Generic import IList, List
uidoc = __revit__.ActiveUIDocument
doc = uidoc.Document
materials = FilteredElementCollector(doc).WherePasses(ElementCategoryFilter(BuiltInCategory.OST_Materials))
material = [i for i in materials if i.Name == "Béton - Coulé sur place - Béton20"]
if len(material) > 0:
mat = material[0]
m_Id = mat.Id
else:
with Transaction(doc, 'Get/create concrete material') as t:
t.Start()
m_Id = Material.Create(doc, "Béton - Coulé sur place - Béton20")
mat = doc.GetElement(m_Id)
mat.MaterialClass = "Béton"
mat.MaterialCategory = "Béton"
mat.Color = Color(192,192,192)
mat.Shininess = 128
mat.Smoothness = 50
asset = StructuralAsset("ConcreteStructuralAsset", StructuralAssetClass.Concrete)
asset.ConcreteCompression = UnitUtils.ConvertToInternalUnits(20, UnitTypeId.Megapascals)
asset.Density = UnitUtils.ConvertToInternalUnits(2500, UnitTypeId.KilogramsPerCubicMeter)
asset.SetPoissonRatio(0.2)
asset.SetYoungModulus(UnitUtils.ConvertToInternalUnits(11000*20**(1/3), UnitTypeId.Megapascals))
struc = PropertySetElement.Create(doc, asset)
mat.SetMaterialAspectByPropertySet(MaterialAspect.Structural, struc.Id)
appar_Id = ElementId(177984)
mat.AppearanceAssetId = appar_Id
t.Commit()
What do you want to do?
It seems you want to do this:
IF the material exists:
check and set the specs.
ELSE
create a new material with that name and set the specs of the new material?
But if your code should do as you put it:
material will return false if no materials match your i.Name. So please don’t use len to check that.
# why not use pyrevit modules?
# # math not used, don't include it.
# import math
from Autodesk.Revit.DB import *
# from System.Collections.Generic import IList, List
uidoc = __revit__.ActiveUIDocument
doc = uidoc.Document
material_check = "Béton - Coulé sur place - Béton20
materials = FilteredElementCollector(doc).WherePasses(ElementCategoryFilter(BuiltInCategory.OST_Materials))
material = [i for i in materials if i.Name == material_check]
if material:
mat = material[0]
m_Id = mat.Id
else:
with Transaction(doc, 'Get/create concrete material') as t:
t.Start()
m_Id = Material.Create(doc, material_check)
....
t.Commit()
This code below works just fine.
from pyrevit import revit, DB
selection = revit.get_selection()
material_check = "material_name_here"
materials = DB.FilteredElementCollector(revit.doc).WherePasses(DB.ElementCategoryFilter(DB.BuiltInCategory.OST_Materials))
materials_matching = [i for i in materials if i.Name == material_check]
#if materials_matching:
# for material_matching in materials_matching:
# print material_matching.Name
if materials_matching:
print materials_matching[0].Name
else:
print "no material found with the name '{}'".format(material_check)
Thx @jvandermeulen for your replay, I practically used the same approach as you
I finally solved the issue in my main script (which includes a part for getting/creating material). Sorry, @Jean-Marc, I was wrong—the issue was due to the level elevation, which does not return the same value when I switched from the Architecture to the Structure template to test my script. I have now fixed it.
I’m coming from Dynamo, and I’m not yet familiar with the pyrevit modules.