IndexError: index out of range: 0

Hi All,

I’m getting an IndexError in the RPS console:

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()

Any Help would be appreciated

Thanks.

To help you debug before your if statement

print(material)
print(len(material))
print(type(material))
2 Likes

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)
2 Likes

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.

Thanks for All.

2 Likes