Change Revit Generic Model Category to Specialty Equipment in Dynamo

Hello,

I need to take all generic models in a Revit file and change them to specialty equipment. I know I can do this individually in the Revit Family but I have such a large number of families to convert I am hoping Dynamo can create a more streamlined process. I am doing this to be able to view all the equipment pieces in a Revit schedule with their corresponding room number and since generic models are are not room aware I need to change them to a family category that is. I am new to Dynamo but I have been able to get this together from blogs etc. Maybe its relevant or not… Any ideas on how to accomplish this change?

Dynamo

Changing categories creates tons of graphics issues, from line weights to cut graphics (or not cutting at all). Instead of changing the model category, why not enable the room calculation point in the families? Once that is done I believe that they will report the containing room as any other “room aware” family type would.

See this post for help on enabling that feature
http://dynamobim.org/forums/topic/modify-room-calculation-point-toggle-builtin-parameter/

Thanks Jacob,

The link you sent was helpful and I think this works well but I have a few questions:

I started with using part of Konrad’s dynamo script. The snag I encounter is that the families I want to allow 'room calculation point’s for are from the model (they come from a consultants model that I need to edit) so saving each family to a folder defeats the usefulness of dynamo. So I was attempting to marry the category selection with the room calculation point Python script albeit unsuccessfully. Is there a way to carry elements of a category over? I tried using a List and Group but no luck there…

Also where does the “D:\12_Dynamo073 EditFamilyAndReload” come from? Is this something he created or within Dynamo?

The package Beaker has a node called DocumentUtilities.GetFamilyDocument that will give you the documents for the families within the model:

But with using this node, you will have to modify the Python code you are using because right now it is pulling the document from a file path. Could you copy and paste the Python code here as preformatted text?

EDIT: Scratch the Spring nodes collecting the elements from the linked documents. You would want to run the graph within your linked model so you can load them back into the project

2 Likes

I think the code is to be found in the link sent by Jacob :slightly_smiling_face:

Oops you’re right - I only saw screenshots of it and didn’t see it pasted, but it is in the .dyn file uploaded towards the end!

@anp5366 Here is an edited Python script that will work with the outputs of the Beaker package DocumentUtilities.GetFamilyDocument node:

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

#Import Elemet wrapper extension methods
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)

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

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

#Import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import System

#Import Python
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

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

famDocs = IN[0]
paramName = IN[1]
value = IN[2]

if not isinstance(famDocs, list): famDocs = [famDocs]

class FamliyOption(IFamilyLoadOptions):
	def OnFamilyFound(self, familyInUse, overwriteParameterValues):
		overwriteParameterValues = True
		return True

	def OnSharedFamilyFound(self, sharedFamily, familyInUse, source, overwriteParameterValues):
		return True

def GetBuiltInParam(paramName):
	builtInParams = System.Enum.GetValues(BuiltInParameter)
	test = []
	for i in builtInParams:
		if i.ToString() == paramName:
			test.append(i)
			break
		else:
			continue
	if len(test) == 0:
		return None
	else:
		return test[0]
try:
	errorReport = None
	outValue = []
	for famDoc in famDocs:
		ownerFamily = famDoc.OwnerFamily
		bip = GetBuiltInParam(paramName)
		param = ownerFamily.get_Parameter(bip)
		TransactionManager.Instance.EnsureInTransaction(famDoc)
		param.Set(value)
		TransactionManager.Instance.TransactionTaskDone()
		outValue.append(famDoc.LoadFamily(doc, FamliyOption()))
except:
	#if error accurs anywhere in the process catch it
	import traceback
	errorReport = traceback.format_exc()

#Assign your output to the OUT variable
if errorReport == None:
	OUT = value
else:
	OUT = errorReport

This will let you turn the room calculation point on or off for families while you are in the project environment.

2 Likes

For what it’s worth I feel it’s best practice to save everything twice when having to modify a consultant family. The families and their model should be saved first, then saved as an edited copy. You can quickly save the families to the network/local disk into a folder using the save as library function, and then copy that folder into an “as recieved” folder so you have an “unedited” version and a version to use Konrad’s script on. This will allow you to roll back to the “original” families if something becomes an issue down the line. Best for you to decide what’s best for your project though.

2 Likes

I am trying to modify multiple items instead of just 1, How do I change the code so it loops through all the selected items?