A family has type parameters, some of which are of Type: Family Type. Such parameters allow switching out nested family types: Autodesk Revit: Create a Nested Family with Interchangeable Components.
How does one generate a dictionary for the nested family types in order to set them by [Family Name] and [Type Name] from within Dynamo? My choice is to allow some error tolerance in the data in that the concatenation of the [Family Name] + [Type Name] is used as a “unique” identifier for the dictionary, the uniqueness of which is not necessarily true. Hence, care should be taken during production that this concatenation is indeed unique. The dictionary passes a [Nested Family Type Reference] as a value.
The required nested family type can now be requested from the dictionary using a concatenation of the [Family Name] + [Type Name]. In the graph below, some of the input values were not found in the dictionary, and the setting of the parameter therefore excludes “null” values.
Within a python node: given the family name, select all the family’s types using a filter. Use the first family type and fetch all its parameters. Iterate through the parameters and then, if the parameter is op Type: Family Type, record the nested [Family Names], [Type Names] and [Nested Family Type References].
#2019
#paul@mgfx.co.za
import clr
import sys
clr.AddReference(“ProtoGeometry”)
from Autodesk.DesignScript.Geometry import *
import math
sys.path.append(r’C:\Program Files (x86)\IronPython 2.7\Lib’)
clr.AddReference(“RevitNodes”)
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference(“RevitServices”) # Import DocumentManager
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
import traceback
clr.AddReference(‘RevitAPI’) #import clr
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Plumbing import *
clr.ImportExtensions(Revit.Elements)
import System
clr.AddReference(“DSCoreNodes”)
from DSCore import *
doc = DocumentManager.Instance.CurrentDBDocument
familyNameIn = IN[0]
familyNames = []
typeNames = []
nestedFamilyTypeReferences = []
bip = BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM
provider = ParameterValueProvider(ElementId(bip))
evaluator = FilterStringEquals();
rule = FilterStringRule(provider, evaluator, familyNameIn, True);
filter = ElementParameterFilter(rule);
familySymbols = FilteredElementCollector(doc).OfClass(FamilySymbol).WherePasses(filter).ToElements()
family = familySymbols[0].Family
for parameter in familySymbols[0].Parameters:
if parameter.Definition.ParameterType == ParameterType.FamilyType:
for nestedFamilyTypeReference in family.GetFamilyTypeParameterValues(parameter.Id):
typeNames.append(doc.GetElement(nestedFamilyTypeReference).TypeName)
familyNames.append(doc.GetElement(nestedFamilyTypeReference).FamilyName)
nestedFamilyTypeReferences.append(doc.GetElement(nestedFamilyTypeReference))
OUT = familyNames, typeNames, nestedFamilyTypeReferences
The output from the Python node is used to create the Dictionary. While it is possible to output the values as row vectors for each relevant parameter, in this case the list is output as one-dimensional for simplicity in the application of the dictionary.