FamilyInstance.GetFamily Node equivalent in Python?

Hello!
I want to do the equivalent of the FamilyInstance.GetFamily node. I am fundamentally missing a python design pattern to achieve this result. The attached image is what I want to achieve in Python. My custom python node gets the architects linked title-block(s). Many times there is more than one title-block. I dig through them and find the one used on the primary sheets. Now I have a FamilyInstance but need the Family. I struggle to make the connection of how to get the Family, of the instance from the filter using the OfClass(FamilySymbol) . I see <FamilyInstance>.GetType but the result is not the element. Any help is appreciated.

famInstance = FilteredElementCollector(linkDoc[0]).OfCategory(BuiltInCategory.OST_TitleBlocks).WhereElementIsNotElementType().ToElements()

famSymbol   = FilteredElementCollector(linkDoc[0]).OfCategory(BuiltInCategory.OST_TitleBlocks).OfClass(FamilySymbol).ToElements()

I am aware of the following similar question,https://forum.dynamobim.com/t/python-help-family-from-familytype/20574/3?u=darickbrokaw. However the shinny Out of the box node FamilyInstance.GetFamily makes it look so easy and wonder if there is a better way.

You haven’t posted your Python code so we can’t really help directly, but this should help you square yourself away: Family Property

1 Like

Keep in mind the FamilySymbol is the Type, not the Family. I don’t believe a FilteredElementCollector is going to necessarily return the Families in the same order as the Instances either. It would be much simpler to just get the FamilySymbol from the Instance and the Family from the FamilySymbol.

1 Like

here is the code with the .Family I htink you are speaking of but it does not give the Family result. I must be doing something wrong…?

# Enable Python support and load DesignScript library
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

from System.Collections.Generic import List

# collect current document. 
doc = DocumentManager.Instance.CurrentDBDocument
# collect linked revit documents 
linkedDoc = FilteredElementCollector(doc).OfClass(RevitLinkInstance)

#
linkDoc = []

# get the linked document 
for i in linkedDoc:
	linkDoc.append(i.GetLinkDocument())
	
# collect all grids from linked document. 
famInstance = FilteredElementCollector(linkDoc[0]).OfCategory(BuiltInCategory.OST_TitleBlocks).WhereElementIsNotElementType().ToElements()

famSymbol = UnwrapElement(FilteredElementCollector(linkDoc[0]).OfCategory(BuiltInCategory.OST_TitleBlocks).OfClass(FamilySymbol).ToElements())


OUT = famInstance.Family

How does one do this? Thank you for helping.

They’re all just properties of each other. Take a look at the link Jacob posted.

1 Like

You can’t pull the family from the family instance. You first need to get the family symbol. In your case: parentFamily = famSymbol.Family

Alternatively you can work with your instances, but you will need to get the Symbol property first.

1 Like

There are a few issues you need to resolve and be aware of:

  1. If you want to use Dynamo OOTB nodes with outputs from your Python script where you are making explicit Revit API calls, you have to wrap the elements using Dynamo’s Revit Element wrapper class otherwise you’ll see invalid input exceptions as per your screenshots.
  2. Any methods (nodes) you see in Dynamo are from Dynamo-specific libraries, FamilyInstance.GetFamily() for example is from Dynamo’s RevitNodes library and it does not exist in the Revit API hence if you make calls to the Revit API - which returns Revit API objects - and try to use method calls from Dynamo’s RevitNodes its never going to work as the types are completely different even though both are analogous (e.g. Element > Element).
  3. The filtered element collector returns a collection, not a single item, so the way you’ve called .Family won’t even if it could as it needs to be called on a single item not a collection of items (so you need to iterate the collection using a for statement for example, then make the call on each item as you iterate).

To fix this you need to:

  1. Create a new list to store your family instances.
  2. Write a for statement and iterate the result from the filtered element collector.
  3. Wrap the instance using the Dynamo wrapper (by calling ToDSType(True) on the instance).
  4. Return the list.

One other consideration; since you’re already in the Revit API context in Python its kind of pointless going to all the effort to write code and make calls to the Revit API only to use a Dynamo node to get the data you need. Why not just get the family in your code and do-away with as many nodes as possible? To get the family you need to access the parameters of the instance, then use the BuiltInParameter.ELEM_FAMILY_PARAM to get the Family object.

3 Likes

Nick_Boyts, JacobSmall, Thomas_Mahon

Thank you all for helping me out. I am working through it and will post my results in a bit. Again, THANK YOU!