Get Instance Parameter from a set of Family Types

Hi everyone.
I have the following issue working with Python Node:
I’m getting a list of elements (in this case Structural framing and columns), filtered them according to a Description (which is a Type parameter value). What I get is a list of Family Types, but when I try to apply a LookupParameter method in order to get the “Volume” from each of the items in that list I only get null values.
I guess that this is because “Volume” is an instance parameter while my list is made of Family Types. So, how can I get the instance parameter “Volume” from this "Family Types"list?
This is the code I’ve written inside Python Node:

import sys
import clr
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

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

#Get Elements
elemSecVar = []
columnas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).WhereElementIsNotElementType()
for columna in columnas:
	id = columna.GetTypeId()
	elemento = doc.GetElement(id)
	descripcion = elemento.LookupParameter("Description").AsString()
	if descripcion is not None and descripcion.Contains("SV"):
		elemSecVar.append(elemento)
vigas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralFraming).WhereElementIsNotElementType()
for viga in vigas:
	idv = viga.GetTypeId()
	elementoV = doc.GetElement(idv)
	descripcionV = elementoV.LookupParameter("Description").AsString()
	if descripcionV is not None and descripcionV.Contains("SV"):
		elemSecVar.append(elementoV)

lista = []
for elem in elemSecVar:
	elemento = elem.LookupParameter("Volume")
	lista.append(elemento)
	

OUT = lista

PRUEBA_VOLUME_EST_01

Any help will be very appreciated

1 Like

Hello @DavidMena

you need to get an instance from type to get instance parameter
a simple example

e = UnwrapElement(IN[0])
eTypeId = e.GetTypeId()
filter = FamilyInstanceFilter(doc, eTypeId)
instance = FilteredElementCollector(doc).OfClass(FamilyInstance).WherePasses(filter).FirstElement()
2 Likes

Thank you for your help @c.poupin . The problem is that first I’m getting a list of family Types that contain a certain string as Description (Which is Type Parameter), then I try to iterate over that list to apply the Instance Filter and, to begin with, it returns me only invalid values as TypeId as you can see in the image. I guess the approach is probably wrong from the beggining, so I would aprreciate if you cast a bit of light over my confusion. Thanks!

I’m not sure what end result you want but you can try this (not tested, no model)

import sys
import clr
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

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

#Get Elements
elemSecVar = []
columnas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).WhereElementIsNotElementType()
for columna in columnas:
	id = columna.GetTypeId()
	elemento = doc.GetElement(id)
	descripcion = elemento.LookupParameter("Description").AsString()
	if descripcion is not None and descripcion.Contains("SV"):
		elemSecVar.append(elemento)
vigas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralFraming).WhereElementIsNotElementType()
for viga in vigas:
	idv = viga.GetTypeId()
	elementoV = doc.GetElement(idv)
	descripcionV = elementoV.LookupParameter("Description").AsString()
	if descripcionV is not None and descripcionV.Contains("SV"):
		elemSecVar.append(elementoV)

lista = []
for elemTyp in elemSecVar:
	filter = FamilyInstanceFilter(doc, elemTyp.Id)
	all_elements = FilteredElementCollector(doc).WherePasses(filter).WhereElementIsNotElementType()
	for elem in all_elements:
		para = elem.LookupParameter("Volume")
		if para is not None:
			lista.append(elemento.AsDouble()) # or AsString() ?
	
OUT = lista

Hi @c.poupin . Thanks!
Now it is returning values, but for some reason it is returning more than 2000 values when I only have 90 elements in my model :confused:

Hi @DavidMena

No need to iterate again. You can directly get volumes after you filter familyinstances by Description name (“SV”) this way:

import sys
import clr
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

#Get Elements
elemSecVar = []
columnas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).WhereElementIsNotElementType()
for columna in columnas:
	id = columna.GetTypeId()
	elemento = doc.GetElement(id)
	descripcion = elemento.LookupParameter("Description").AsString()
	if descripcion is not None and descripcion.Contains("SV"):
		elemSecVar.append(columna.LookupParameter("Volume").AsDouble())
		
vigas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralFraming).WhereElementIsNotElementType()
for viga in vigas:
	idv = viga.GetTypeId()
	elementoV = doc.GetElement(idv)
	descripcionV = elementoV.LookupParameter("Description").AsString()
	if descripcionV is not None and descripcionV.Contains("SV"):
		elemSecVar.append(viga.LookupParameter("Volume").AsDouble())

OUT = elemSecVar

3 Likes

That was it!
As you said, no need to iterate again. Just append the element to the list after filtering it. It worked perfectly!
Thanks :slight_smile: