Get/Create material issue

Hi All @c.poupin

I’m confused why I can’t get or create a concrete material which I’m sure that is not listed in the materials within the document (Note: I’m working in the architecture template and the material I’m looking for is listed in the structure template it’s named Béton - Coulé sur place - Béton20 and it’s Id is 177816 which I need to use it’s StructuralAsset)

To be sure that the material I’m looking for is not listed within the document I filtered all existing materials, and I obtained those concrete materials:

Maçonnerie - Béton (Material Name)
853 (Material Id)
Béton (Material Class)

Béton, coulé sur place (Material Name)
183853 (Material Id)
Béton (Material Class)

I’m receiving this error:

image

Here my code:

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)

# Filtering All Materials Category
materials = FilteredElementCollector(doc).WherePasses(ElementCategoryFilter(BuiltInCategory.OST_Materials))
 

t = Transaction(doc, 'Get/create concrete material')

t.Start()
for m in materials: 
    if m.Name == "Béton - Coulé sur place - Béton20":
        mat = m
        m_Id = mat.Id
    else:
        m_Id = Material.Create(doc, "Béton - Coulé sur place - Béton20")
        mat = doc.GetElement(m_Id)
t.Commit()

Any help would be appreciated.

Thanks.

Offhand it looks like it’s in your for loop.

You’re asking the computer to do this:

For every material in the document, if the name is "Béton - Coulé sur place - Béton20" then return the material; otherwise try and create the material named "Béton - Coulé sur place - Béton20".

So if the first material is named “default” you’re telling it to create the material named "Béton - Coulé sur place - Béton20". Then if the second material is called “Brick”, you’re once again telling it to create the material called "Béton - Coulé sur place - Béton20", but it can’t as that material already exists.

Instead of for, ask if the material named "Béton - Coulé sur place - Béton20" is in the list of material names.

Something like this (not at a PC to test with):

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 = m
    m_Id = mat.Id
else:
    t = Transaction(doc, 'Get/create concrete material')
    t.Start()
    m_Id = Material.Create(doc, "Béton - Coulé sur place - Béton20")
    mat = doc.GetElement(m_Id)
    t.Commit()

OUT = m_Id, mat
2 Likes

Oh my bad!!..I didn’t notice the glaring mistake I made… it was due to fatigue.

Thanks a lot @jacob.small

1 Like

Happens to us all.

One thing you can do to help next time and with larger code bases, is comment each line as if you were explaining the code to an intern until you find the issue. Also helps you review the code in [6, 12, 24, 48] months time. :slight_smile:

1 Like