I’m searching for a method to replace familyinstances (of the same category). I don’t want to change the type! I want to change the whole family using dynamo.
I’ve tried to get the points of the existing instances and place the new instances by this information. But I’m not able to get the reference plane or face for placing the new instances correctly.
Thanks for your help! I’ve tried it yesterday: If i delete the “first” family, the host of the “second” family changes to “not associated”. In case of moving the ceiling, the second family won’t move with it.
I’ve also tried to set the parameter “host” by the value of the first family (familyInstance.getHost). Unfortunately it is a read-only Parameter.
edit: I read your post again… If i use element.faces of the host (ceiling) of the first family, the elevation is set to “0” … I keep trying
As long as the hosting is the same you just need to use SetParameterByName node to set the family. If you’re changing from say a point-and-place family to a face based family you will have to create a new instance with the appropriate hosting in mind.
I couldn’t find the script for now. But imho there is nothing important missing.
Input of the FamilyInstance.GetHost node is the list of the “old” instances.
Input of the FamilyInstance.ByFace node is the list of the “new” instances.
I trying to replace family as well using set parameter value by Name … and I define the parameter name as Family but it isn’t working anyone has an idea?
import clr
import sys
pyPath = r"C:\Program Files (x86)\IronPython 2.7\Lib"
sys.path.append(pyPath)
import System
import System.Collections
#Access to Revit Document
clr.AddReference("RevitServices")
import RevitServices
#To Get Doc, UI and Application Objects
from RevitServices.Persistence import DocumentManager
#Needed to make any changes in Revit
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference("RevitAPIUI")
from Autodesk.Revit.UI import *
import traceback
doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIDocument
app = DocumentManager.Instance.CurrentUIApplication.Application
#Define Lists
elemTypeName = []
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
famTypeToChange = IN[0]
famTypeToChangeTo = IN[1]
famTypeToChangeName = famTypeToChange.Name.ToString()
famTypeToChangeFamName = UnwrapElement(famTypeToChange).FamilyName.ToString()
famTypeToChangeToName = famTypeToChangeTo.Name.ToString()
famTypeToChangeToFamName = UnwrapElement(famTypeToChange).FamilyName.ToString()
TransactionManager.Instance.EnsureInTransaction(doc)
#Get Elements with Family Name Matching info Above
string = famTypeToChangeFamName
case = IN[2]
search = "Family"
bips = System.Enum.GetValues(BuiltInParameter)
bm = doc.ParameterBindings
bmlist = bm.ForwardIterator()
paramId = None
testout = []
while bmlist.MoveNext():
binddef = bmlist.Key
testout.append(binddef.Name)
if binddef.Name == search:
paramId = binddef.Id
break
param = None
if paramId == None:
biplist = []
for bip in bips:
try:
name = LabelUtils.GetLabelFor(bip)
except:
continue
if name == search:
biplist.append(bip)
sharedparamrule = SharedParameterApplicableRule(search)
evaluator = FilterStringContains()
parameter = None
if paramId == None and len(biplist) == 0:
coll = FilteredElementCollector(doc)
sharedparams = coll.OfClass(ParameterElement)
for param in sharedparams:
name = param.GetDefinition().Name
if name == search:
parameter = param
if parameter != None:
ruleslist = List[FilterRule]()
provider = ParameterValueProvider(parameter.Id)
filterrule = FilterStringRule(provider, evaluator, string , case)
ruleslist.Add(filterrule)
ruleslist.Add(sharedparamrule)
paramFilter = ElementParameterFilter(ruleslist)
collector = FilteredElementCollector(doc)
collector.OfClass(FamilyInstance).WherePasses(paramFilter)
collector2 = FilteredElementCollector(doc)
collector2.OfClass(HostObject).WherePasses(paramFilter)
collector2.UnionWith(collector)
elif paramId == None:
if len(biplist) == 1:
provider = ParameterValueProvider(ElementId(biplist[0]))
filterrule = FilterStringRule(provider, evaluator, string , case)
paramFilter = ElementParameterFilter(filterrule)
collector = FilteredElementCollector(doc)
collector.OfClass(FamilyInstance).WherePasses(paramFilter)
collector2 = FilteredElementCollector(doc)
collector2.OfClass(HostObject).WherePasses(paramFilter)
collector2.UnionWith(collector)
else:
provider = ParameterValueProvider(ElementId(biplist[0]))
filterrule = FilterStringRule(provider, evaluator, string , case)
paramFilter = ElementParameterFilter(filterrule)
collector = FilteredElementCollector(doc)
collector.OfClass(FamilyInstance).WherePasses(paramFilter)
collector2 = FilteredElementCollector(doc)
collector2.OfClass(HostObject).WherePasses(paramFilter)
collector2.UnionWith(collector)
for i,param in enumerate(biplist):
if i == 0:
continue
provider = ParameterValueProvider(ElementId(param))
filterrule = FilterStringRule(provider, evaluator, string , case)
paramFilter = ElementParameterFilter(filterrule)
tempcollector1 = FilteredElementCollector(doc)
tempcollector1.OfClass(FamilyInstance).WherePasses(paramFilter)
tempcollector2 = FilteredElementCollector(doc)
tempcollector2.OfClass(HostObject).WherePasses(paramFilter)
tempcollector2.UnionWith(tempcollector1)
collector2.UnionWith(tempcollector2)
else:
ruleslist = List[FilterRule]()
provider = ParameterValueProvider(paramId)
filterrule = FilterStringRule(provider, evaluator, string , case)
ruleslist.Add(filterrule)
ruleslist.Add(sharedparamrule)
paramFilter = ElementParameterFilter(ruleslist)
collector = FilteredElementCollector(doc)
collector.OfClass(FamilyInstance).WherePasses(paramFilter)
collector2 = FilteredElementCollector(doc)
collector2.OfClass(HostObject).WherePasses(paramFilter)
collector2.UnionWith(collector)
if parameter == None and paramId == None and len(biplist) == 0:
OUT = "Does not work with non-shared family parameters"
else:
elements = collector2.ToElements()
TransactionManager.Instance.EnsureInTransaction(doc)
#Check Family Names of Selected, check to ensure Family Type Matches Also
try:
elems = []
for e in elements:
elemTypeName = e.Name == famTypeToChangeName
if elemTypeName == True:
elems.append(e)
except:
OUT = elemTypeName = "No Elements Match"
#Get All Parameter Names, and Values for Any that have a value
#Set New Family Name and Type, Set Parameter Values
Output = []
try:
for setElems in elems:
Output.append("Start")
elemParamMap = []
filterReadOnlyFalseAll = []
elemParamName = []
elemParamNameAll = []
elemParamValue = []
elemParamValueAll = []
parameter = []
elemParamMap = setElems.ParametersMap
for ePS in elemParamMap:
if not ePS.IsReadOnly:
filterReadOnlyFalseAll.append(ePS)
for fROFA in filterReadOnlyFalseAll:
if fROFA.UserModifiable:
elemParamName = fROFA.Definition.Name
elemParamNameAll.append(elemParamName)
elemParamValue = None
if fROFA.StorageType == StorageType.String:
elemParamValue = fROFA.AsString()
else:
elemParamValue = fROFA.AsValueString()
elemParamValueAll.append(elemParamValue)
TransactionManager.Instance.EnsureInTransaction(doc)
setElems.ChangeTypeId(UnwrapElement(famTypeToChangeTo).Id)
TransactionManager.Instance.EnsureInTransaction(doc)
TransactionManager.Instance.EnsureInTransaction(doc)
for elemParamName, elemParamValue in zip(elemParamNameAll, elemParamValueAll):
if elemParamValue == elemParamName:
elemParamValue = elemParamName.Id
Output.add(elemParamValue)
parameter = setElems.LookupParameter(elemParamName)
if parameter.StorageType == StorageType.String:
parameter.Set(str(elemParamValue))
else:
parameter.SetValueString(elemParamValue)
TransactionManager.Instance.EnsureInTransaction(doc)
Output.append("Done")
except ValueError as ve:
Output.append("Family Swap Failed")
Output.append(ve)
OUT = elems.Count, Output
It is still a prototype script,(of which a majority of the code is from MEPover Filter Contains node) I am missing the ability to handle parameters with shared parameter(what my company calls ctrl parameters that allow a drop down selection on the properties bar) that you need to grab their elementId instead of their string.