SetParameterByName to wall object in Python

Hi All,

I have a little question. I have this short Python that does 2 tasks:

  • Corrects the level name according to my criteria.
  • Assign a determined RebarCoverType to the wall elements collected.

The last task I can’t to get it done, I have this message:.

image

The Code:

import clr

clr.AddReference('RevitNodes')
import Revit

#importa el ToProtoType y ToRevitType
clr.ImportExtensions(Revit.GeometryConversion)

clr.AddReference('ProtoGeometry')
import Autodesk.DesignScript.Geometry
from Autodesk.DesignScript.Geometry import *

#Importar el Docuement Manager y Transacciones
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference('System')
from System import *

#Importar la API de Revit
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference('DSCoreNodes')
from DSCore import *


# Datos de entrada
EntradaTonta = IN[0]		#Solo se deja para que funcione el Passthrough.

# Hacer referencia al documento activo.
doc = DocumentManager.Instance.CurrentDBDocument

# Crear un colector de los elementos para ciertas categorias (http://www.revitapidocs.com/2017.1/ba1c5b30-242f-5fdc-8ea9-ec3b61e6e722.htm)
collectorLevels = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels)
collectorWalls = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls)
collectorRebarCover = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_CoverType)

# Inicia la transaccion
TransactionManager.Instance.EnsureInTransaction(doc)

# Genera una lista con todos los
PisosRevit = []
for i in collectorLevels:
    if not ('LevelType' in str(i)):
        if 'FUNDACION' in i.Name:
            i.Name = 'PLANTA DE FUNDACIONES'
        elif ' ' in i.Name:
            i.Name = (i.Name).Replace(' ', '')

# Finaliza la transaccion
TransactionManager.Instance.TransactionTaskDone()

Muros = []
for i in collectorWalls:
    if not ('WallType' in str(i)):
        Muros.append(i)

RebarCover = []
for i in collectorRebarCover:
    RebarCover.append(i)

# Aplica recubrimientos en todos los elementos muro.
for wall in Muros:
    muro = wall
    muro.SetParameterByName("Rebar Cover - Exterior Face", RebarCover[8])
    muro.SetParameterByName("Rebar Cover - Interior Face", RebarCover[8])
    muro.SetParameterByName("Rebar Cover - Other Faces", RebarCover[8])

OUT = []

I know that I’m missing something here, Cold you help me with this please?

Thanks in advance for your time.

Cheers!

try:
muro.LookupParameter(“Rebar Cover - Exterior Face”).Set(RebarCover[8])

Thanks @Tomasz_Puchala. Tried what you recommended but this didn’t solve my problem.

Here is the same script, but using the collections trough Dynamo.

Seteo Inicial.dyn (17.9 KB)

This works just fine.

Thanks in advance!

Thanks, @erfajo! It works like you said. But, I doing the collector to avoid putting the nodes “Categories” and “All Elements of Category”. I want to do this process in Python.
More similar to what I did in the first post.

Is it possible?

Thanks in advance!

WOW! Great! Thanks a lot @erfajo . I didn’t know about the “WhereElementIsNotElementType()” method. Also, I think the “ToElements()” was the stumbling rock here. I’ll adjust my script using your recommendations.

Thanks a lot.

Hi @erfajo:

I managed to adjust my code using you directions:

import clr

clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
clr.AddReference('RevitNodes')

#Importar el Docuement Manager y Transacciones
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Revit and Dynamo modules
from Autodesk.Revit.DB import BuiltInCategory, FilteredElementCollector
from RevitServices.Persistence import DocumentManager
import Revit
clr.ImportExtensions(Revit.Elements)

# Datos de entrada
EntradaTonta = IN[0]		#Solo se deja para que funcione el Passthrough.

# Hacer referencia al documento activo.
doc = DocumentManager.Instance.CurrentDBDocument

# Crear un colector de los elementos para ciertas categorias (http://www.revitapidocs.com/2017.1/ba1c5b30-242f-5fdc-8ea9-ec3b61e6e722.htm)
Niveles = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements())
Muros = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements())
RebarCover = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_CoverType).ToElements()

# Inicia la transaccion
TransactionManager.Instance.EnsureInTransaction(doc)

# Corrige el nombre de los niveles de acuerdo al criterio indicado en el manual.
for i in Niveles:
    if 'FUNDACION' in i.Name:
        i.Name = 'PLANTA DE FUNDACIONES'
    elif ' ' in i.Name:
        i.Name = (i.Name).Replace(' ', '')



# Finaliza la transaccion
TransactionManager.Instance.TransactionTaskDone()

# Aplica recubrimientos en todos los elementos muro.

for wall in Muros:
    muro = wall.ToDSType(True)
    muro.SetParameterByName('Rebar Cover - Exterior Face', RebarCover[8])
    muro.SetParameterByName('Rebar Cover - Interior Face', RebarCover[8])
    muro.SetParameterByName('Rebar Cover - Other Faces', RebarCover[8])

OUT = 'Nombres de pisos corregidos y parametros asignados correctamente.'

But now, if I want to assign a RebarCover Type to the corresponding parameter, the error says: “No parameter found by that name”.

This is weird, because If I look for Element.Parameters, I get the desired Parameter.

Any thoughts?

Thanks in advance for your time.

Hi,

I don’t think it is a SubCategory issue.

Here I made a simple example. I couldn’t replicate the exact error that I’m witnessing:

https://drive.google.com/open?id=1orXqYYt8SvyzkWArdRys_4h5k80NEOHb

Now, I’m getting this error:

image

Thanks in advance!

@erfajo I found the missing piece for the “No parameter found by that name” error. The model had some architectural walls which I couldn’t see in my Structural view. This walls didn’t have the “Structural” option enabled, therefore, they didn’t have Rebar Cover parameters.

The solution you recommended was accurate. So, the problem now is the one explained in my previous post. Is the one from the example provided.

image

Thanks in advance for your time!

Thanks @erfajo! I really appreciate your help. For me was very illustrative this thread!

My final code is like this:

import clr

clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
clr.AddReference('RevitNodes')
clr.AddReference('RevitAPIUI')

from Autodesk.Revit.UI import TaskDialog

#Importar el Docuement Manager y Transacciones
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Revit and Dynamo modules
from Autodesk.Revit.DB import BuiltInCategory, FilteredElementCollector
from RevitServices.Persistence import DocumentManager
import Revit
clr.ImportExtensions(Revit.Elements)

# Hacer referencia al documento activo.
doc = DocumentManager.Instance.CurrentDBDocument

# Crear un colector de los elementos para ciertas categorias (http://www.revitapidocs.com/2017.1/ba1c5b30-242f-5fdc-8ea9-ec3b61e6e722.htm)
Niveles = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements())
Muros = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements())
RebarCover = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_CoverType).ToElements()

# Inicia la transaccion
TransactionManager.Instance.EnsureInTransaction(doc)

# Corrige el nombre de los niveles de acuerdo al criterio indicado en el manual.
for i in Niveles:
    if 'FUNDACION' in i.Name:
        i.Name = 'PLANTA DE FUNDACIONES'
    elif ' ' in i.Name:
        i.Name = (i.Name).Replace(' ', '')

# Finaliza la transaccion
TransactionManager.Instance.TransactionTaskDone()

# Aplica recubrimientos en todos los elementos muro.

# transformar a elementos de Dynamo
coverTypes = []
for cover in RebarCover:
    coverTypes.append(cover.ToDSType(True))

indice = []
for i in range(len(Muros)):
    muro = Muros[i].ToDSType(True)
    if muro.GetParameterValueByName('Structural') == 1:
        muro.SetParameterByName('Rebar Cover - Exterior Face', coverTypes[8])
        muro.SetParameterByName('Rebar Cover - Interior Face', coverTypes[8])
        muro.SetParameterByName('Rebar Cover - Other Faces', coverTypes[8])
    else:
        indice.append(i)

if indice:
    contador = str(len(indice))
else:
    contador = str(0)

OUT = 'Nombres de pisos corregidos y parametros asignados correctamente. Hay ' + contador + ' muros arquitectonicos! Revisar!'
# OUT = indice

Hope it will be useful!

1 Like

Thanks for the advice! I’ll keep it in mind.

Hi @erfajo,

As you suggested this solution (which works just fine!) I’m trying to replicate this procedure directly as a revit plug-inn (C#). I made almost the same, but in this case, it shows me an error saying “the parameter is read-only”.

Do you know why through dynamo I can do it withoput a problem, but through the API I can’t?

This is the thread: https://forums.autodesk.com/t5/revit-api-forum/rebar-cover-types-collector/m-p/7780511/highlight/false#M28680

Thanks in advance for your time!

:smile: I understand (I’m also a novice in C# and I think zero-touch nodes is a pretty good start!). I think that maybe is when you transform the object into a Dynamo object when the “read-only” option is disabled. I’m just guessing here…

Hope if someone comes with a proper explanation of this phenomena.

Cheers!