Python - Get Element Family Name then apply a filter

I’ve read through a few posts on here and i’ve tried a few things but cant quite get it working.

im trying to:-
get all elements of a category in the active view.
get family name of elements
filter out the elements based on the family name containing “???”.

import clr

#Import Revit Nodes
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

dataEnteringNode = IN

#The inputs to this node will be stored as a list in the IN variables.

#Get the project document.
doc = DocumentManager.Instance.CurrentDBDocument

#Filter for category.
collector = FilteredElementCollector(doc, doc.ActiveView.Id)

filter = ElementCategoryFilter(BuiltInCategory.OST_DuctFitting)
category = collector.WherePasses(filter).ToElements()

familyname = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_DuctFitting).WhereElementIsElementType()

#Assign your output to the OUT variable.
OUT = category, familyname

Python_list

im getting all the elements in the category from the active view which is great.

but I cant get the ‘familyname’ to output the actual family name.
from there Id like to filter the elements by the family name so if it contains ‘Bend’ or ‘shoe’ etc

I’ve tried a few things with FamilySymbol, .FamilyName and AsString, based on other threads in on here, but always seem to end up with empty list or errors.

or is there a better way of going about it? finding all instances of a family type and just list out the ones i want to collect?

any advice would be great!

Thanks,

@T_Pover, @Kulkul, @awilliams

Now that you have the family type you should be able to get the family definition, then the name.

See below:

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager

doc = DocumentManager.Instance.CurrentDBDocument

category = UnwrapElement(IN[0])
elements = FilteredElementCollector(doc, doc.ActiveView.Id)\
		.OfCategoryId(category.Id)\
		.WhereElementIsNotElementType()

filtered = []
for e in elements:
	type_id = e.GetTypeId()
	element_type = doc.GetElement(type_id)
	family = element_type.Family
	name = family.Name
	if '???' not in name:
		filtered.append(e)
	
OUT = filtered

What you are assigning to the ‘familyname’ parameter is actually just the FamilySymbol. Get the Family from the FamilySymbol and then get the Name from the Family (this is inherited from the Element class).

I should also note that the above code expects a single Category being provided to input IN[0].

2 Likes

Hello,

another solution similar to that of cgartland

import clr

#Import Revit Nodes
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

#collection filter FamilyInstance in active view
FamInst_filtered = [x for x in FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_DuctFitting).ToElements() if "???" in x.Symbol.FamilyName]

#Assign your output to the OUT variable.
OUT = FamInst_filtered
2 Likes

Thank you for your help guys! both methods worked for me! :star_struck:

I took this and @T_Pover code for MEP connectors :+1::clap: (i’m fining this incredibly useful!) and added a modified version of that to get the ducts connected to the fittings.

@cgartland - i ended up on that Family page quite a few trying to fiqure this out. API doc is starting to make a bit more sense…

import clr

#Import Revit Nodes
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

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

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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

doc = DocumentManager.Instance.CurrentDBDocument
shoe_ducts = []
taper_ducts = []
#collection filter FamilyInstance in active view
Shoes = [x for x in FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_DuctFitting).ToElements() if "Shoe" in x.Symbol.FamilyName]
Tapers = [x for x in FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_DuctFitting).ToElements() if "Taper" in x.Symbol.FamilyName]

for shoe in Shoes:
	shoeset = shoe.MEPModel.ConnectorManager.Connectors
	conn_shoe = []
	for c in shoeset:
		if c.IsConnected:
			for sc in c.AllRefs:
				conn_shoe.append(sc.Owner)
				shoe_ducts.append(conn_shoe)

for taper in Tapers:
	taperset = taper.MEPModel.ConnectorManager.Connectors
	conn_taper = []
	for c in taperset:
		if c.IsConnected:
			for tc in c.AllRefs:
				conn_taper.append(tc.Owner)
				taper_ducts.append(conn_taper)

OUT = shoe_ducts, taper_ducts

so i have a list of elements connected to all the fittings in the view.:partying_face:
sure theres a better way of doing but it works so im happy!

I have purposely added fittings directly after the tapers/shoes, as in this instance i want to find the ducts from these secondary fittings if that makes sense. so my current output has a mix of ducts and duct fittings.

How would i apply a category filter to the output lists already created (shoe_ducts/ taper_ducts)? i’d like to filter out the fittings from these lists, the get their connections & connected duct. (preferably within the same python script).

Or even better would be a loop where it takes the shoes/tapers, find the connectors and the connected elements.

if its a duct append to a list.
elseif its a fitting/accessory/mech equipment, find the connector and the connected element.
if its a duct append to a list.
else if…
and repeat through until there is the first duct element after each taper/shoe connection.

something like this in dynamo but kind of endless until it finds a duct?

1 Like