Custom Family Type Catalog Exporter

Ok, so here is what I have come up with, and what is still not working just right.

  • I exported a Type Catalog from Revit directly and it was actually encoded as UTF-16LE

  • This export maintained special characters / letter as I expected, but broke for Parameter Names / Values with commas.

  • I refactored to encapsulate either of those values when they had a comma

  • I refactored the write to use the codecs class rather than the stream writer.

  1. This enables us to encode as we want to the UTF-16LE or any other as needed
  2. Problem is that for some reason it is hiding an invisible character at the beginning of the text file that is breaking revit.
  • This can be solved in two ways:
  1. Save As from notepad as ANSI
  2. Delete and replace the very first comma on the first line of the file.

There would probably be a way to open and replace the comma, but my first attempts saved the file back as UTF-8 or something other than what it was so I stopped thinking it may need a completely different approach.

#Sean Page, 2021
import clr

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

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

clr.AddReference('System')
from System.Collections.Generic import List
from System import *
from System.IO import StreamWriter
from System.Text import Encoding
import codecs
doc = DocumentManager.Instance.CurrentDBDocument
#Preparing input from dynamo to revit
path = IN[1]
#units = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits
famParams = IN[0]
output = []
famTypes = doc.FamilyManager.Types
#Set up the first line of the Type Catalog with the headers
variables = ''
for param in famParams:
	pType = param.Definition.ParameterType
	pName = param.Definition.Name
	#check to see if the parameter name has a comma and encapsulate with double quoates
	if pName.Contains(','):
		pName = '"'+pName+'"'
	if pType == ParameterType.Length:
		variables += "," + pName + "##LENGTH##FEET"
	elif pType == ParameterType.Area:
		variables += "," + pName + "##AREA##SQUARE_FEET"
	elif pType == ParameterType.Volume:
		variables += "," + pName + "##VOLUME##CUBIC_FEET"
	elif pType == ParameterType.Slope:
		variables += "," + pName + "##SLOPE##SLOPE_DEGREES"
	elif pType == ParameterType.Angle:
		variables += "," + pName + "##ANGLE##DECIMAL DEGREES"
	elif pType == ParameterType.Currency:
		variables += "," + pName + "##CURRENCY##CURRENCY"
	else:
		variables += "," + pName + "##OTHER##"
#Add the headers to the final output
output.Add(variables + '\r\n')
#Iterate each type and get the values for each parameter ased on its Storage Type and Parameter Type
for famType in famTypes:
	typeString = String.Empty
	typeString += famType.Name
	for param in famParams:
		pType = param.Definition.ParameterType
		sType = param.StorageType
		value = String.Empty
		if sType == StorageType.Double:
			if pType == ParameterType.Angle:
				value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),DisplayUnitType.DUT_DECIMAL_DEGREES).ToString()
			elif pType == ParameterType.Slope:
				value = UnitUtils.ConvertFromInternalUnits(famType.AsDouble(param),DisplayUnitType.DUT_SLOPE_DEGREES).ToString()
			else:
				value = famType.AsDouble(param).ToString()
		if sType == StorageType.Integer:
			value = famType.AsInteger(param).ToString()
		if sType == StorageType.String:
			value = famType.AsString(param)
		if sType == StorageType.ElementId:
			eid = famType.AsElementId(param)
			elem = doc.GetElement(eid)
			try:
				value = Element.Name.__get__(elem)
			except:
				#This catches materials specifically that are "<Default>" and don't have a name
				value = String.Empty
		#Check for commas in the value and encapsulate with double quotes as needed
		if value.Contains(','):
			value = '"'+value+'"'
		#Add each value for each parameter
		typeString += ","+value
	#Add all values for each Family Type	
	output.Add(typeString + '\r\n')
outfile = codecs.open(path, 'w', encoding='utf-16-le')
try:
	#Write each line to a txt file while encoding for special characters
	for line in output:
		outfile.write(line)
	outfile.close()
	OUT = output
except:
	outfile.close()
	OUT = "Failed to Write File"

Selected Family Type Catalog_v2.dyn (37.1 KB)

2 Likes