Hi i try to write simple code to batch “Change type” for few systems but i stopped on method “ChangeTypeId”. Now my code change pipes type but leaves pipe fittings. There is a method which works like:
It’s anoying to change type for each system…
Thank you in advance!
import System
import os
from rpw import revit
from Autodesk.Revit.UI.Selection import *
from Autodesk.Revit.DB import *
from pyrevit import forms
from pyrevit import output
doc = revit.doc
uidoc = revit.uidoc
## Class and def
class CustomISelectionFilter(ISelectionFilter):
def __init__(self, nom_categorie):
self.nom_categorie = nom_categorie
def AllowElement(self, e):
if e.Category.Name in self.nom_categorie:
# if self.nom_categorie.Contains(e.Category.Name):
#if e.Category.Name == self.nom_categorie:
return True
else:
return False
def AllowReference(self, ref, point):
return true
## Picking elements
with forms.WarningBar(title="Pick elements in model[pipes/pipe fittings"):
collector = uidoc.Selection.PickObjects(ObjectType.Element,CustomISelectionFilter("Pipes Pipe Fittings"))
for i in collector:
el=doc.GetElement(i.ElementId)
print(el.GetTypeId)
transaction = Transaction(doc, 'Change type - PYLAB')
transaction.Start()
for i in collector:
try:
el=doc.GetElement(i.ElementId)
el.ChangeTypeId(ElementId(142438))
except Exception as e:
print(e)
transaction.Commit()
Actually, you can change fitting types, but only to valid fitting types (as per the pipe types routing preferences)
so let’s say you have a target pipe type, then after changing all pipe’s type to that one, you have to change all fitting types to the new types which are defined in the new pipe type’s routing preferences, if that makes sense.
rpm = pipe_type.RoutingPreferenceManager
rc = DB.RoutingConditions(DB.RoutingPreferenceErrorLevel.None)
rc.AppendCondition(DB.RoutingCondition(size)) # size = size of the pipe
try:
mech_fitting = fitting.MEPModel
except InvalidObjectException:
continue
part_type = mech_fitting.PartType
if part_type == DB.PartType.Elbow:
logger.debug('it is an Elbow')
new_fitting_id = rpm.GetMEPPartId(
DB.RoutingPreferenceRuleGroupType.Elbows,
rc
)
elif part_type == DB.PartType.Tee:
logger.debug('it is a Tee')
new_fitting_id = rpm.GetMEPPartId(
DB.RoutingPreferenceRuleGroupType.Junctions,
rc
)
elif part_type == DB.PartType.Cross:
logger.debug('it is a Cross')
new_fitting_id = rpm.GetMEPPartId(
DB.RoutingPreferenceRuleGroupType.Crosses,
rc
)
else:
new_fitting_id = None
logger.debug('current fitting id: {}'.format(fitting.GetTypeId()))
if (new_fitting_id
and fitting.Id != new_fitting_id
and new_fitting_id.IntegerValue != -1):
logger.debug('new fitting id: {}'.format(new_fitting_id))
fitting.ChangeTypeId(new_fitting_id)
Thank you for your answer. This is the way i am looking for! I rewrite code from you to better understand the whole process. I have one problem. It is posible to get MEPPartId by size in criterion?
Now i can pick only one type of MEPPart by index… I want to change pipe fitting by different sizes.
My code:
import os
from Autodesk.Revit.UI.Selection import *
from Autodesk.Revit.DB import *
from pyrevit import forms
from pyrevit import output
from rpw import revit
doc = revit.doc
uidoc = revit.uidoc
## Class and def
class CustomISelectionFilter(ISelectionFilter):
def __init__(self, nom_categorie):
self.nom_categorie = nom_categorie
def AllowElement(self, e):
if e.Category.Name in self.nom_categorie:
# if self.nom_categorie.Contains(e.Category.Name):
#if e.Category.Name == self.nom_categorie:
return True
else:
return False
def AllowReference(self, ref, point):
return true
def Pargetstr(element, name):
return (element.GetParameters(name))[0].AsValueString()
def Parget(element, name):
return (element.GetParameters(name))[0].AsString()
## Picking elements
with forms.WarningBar(title="Pick elements in model[pipes/pipe fittings"):
collector = uidoc.Selection.PickObjects(ObjectType.Element,CustomISelectionFilter("Pipes Pipe Fittings"))
pipe_type = doc.GetElement(ElementId(261488))
rpm = pipe_type.RoutingPreferenceManager
rc = RoutingConditions(RoutingPreferenceErrorLevel.None)
print(pipe_type)
print(rpm)
transaction = Transaction(doc, 'Add insulation - PYLAB')
transaction.Start()
# for loop through picked elements
for i in collector:
i = doc.GetElement(i)
fitting = i
i = i.MEPModel
mech_fitting = i.PartType
print(mech_fitting)
# get routing preference MEPPartId
if mech_fitting == PartType.Elbow:
print('it is an Elbow')
new_fitting_id = rpm.GetMEPPartId(
RoutingPreferenceRuleGroupType.Elbows,
rc)
part_fitting_id = rpm.GetRule(
RoutingPreferenceRuleGroupType.Elbows,
0)
part_fitting_id = part_fitting_id.MEPPartId
print(new_fitting_id)
print(part_fitting_id)
fitting.ChangeTypeId(ElementId(631474)) # change by preselect id
transaction.Commit()
You will need to have a reducer on either side, so I guess you should use the desired fitting size. My use case set a constant size for the whole branch, so I never had to handle these kind of situations.
Paweł Kińczyk (c)
from Autodesk.Revit.UI.Selection import *
from Autodesk.Revit.DB import *
from pyrevit import forms
from rpw import revit
# Get revit model
doc = revit.doc
uidoc = revit.uidoc
# Class and def
class CustomISelectionFilter(ISelectionFilter):
def __init__(self, nom_categorie):
self.nom_categorie = nom_categorie
def AllowElement(self, e):
if e.Category.Name in self.nom_categorie:
# if self.nom_categorie.Contains(e.Category.Name):
# if e.Category.Name == self.nom_categorie:
return True
else:
return False
def AllowReference(self, ref, point):
return True
def get_dict_of_elements(build_in_category):
elements = FilteredElementCollector(doc).OfCategory(
build_in_category).WhereElementIsElementType().ToElements()
return {Element.Name.GetValue(e): e for e in elements}
# Picking elements
with forms.WarningBar(title="Pick elements in model[pipes/pipe fittings]"):
collector = uidoc.Selection.PickObjects(
ObjectType.Element, CustomISelectionFilter("Pipes Pipe Fittings"))
# Get pipe types
pipe_types_dict = get_dict_of_elements(BuiltInCategory.OST_PipeCurves)
# Chose pipe type you want to change
pipe_type_name = forms.CommandSwitchWindow.show(pipe_types_dict.keys(), message='Select pipe type',
recognize_access_key=False)
# Get routing preference
if pipe_type_name == None:
forms.alert("You didn't pick any pipe type", exitscript=True)
raise Exception("You didn't pick any pipe type")
pipe_type = pipe_types_dict[pipe_type_name]
rpm = pipe_type.RoutingPreferenceManager
rc = RoutingConditions(RoutingPreferenceErrorLevel.None)
# Clear unuse elements
del pipe_types_dict
# Sort elements pipe fittings/pipes
collector_fittings = []
collector_pipes = []
for element in collector:
element_category = doc.GetElement(
element).LookupParameter("Category").AsValueString()
if element_category == "Pipes":
collector_pipes.append(element)
else:
collector_fittings.append(element)
# Clear unuse elements
del collector
transaction = Transaction(doc, 'Batch change pipe - PYLAB')
transaction.Start()
# for loop through picked elements
for element in collector_pipes:
try:
print('it is a Pipe')
element = doc.GetElement(element)
element.ChangeTypeId(pipe_type.Id)
except Exception as e:
print("Pipe error")
print(e)
for element in collector_fittings:
refs = []
try:
element = doc.GetElement(element)
fitting = element
element = element.MEPModel
# Get info about connected elements
connectors = element.ConnectorManager.Connectors
size_fit = float(0)
for c in connectors:
for r in c.AllRefs:
c_size = float(r.Owner.LookupParameter("Size").AsString()[0:3])
print(c_size)
if size_fit <= c_size:
size_fit = c_size
rc.AppendCondition(RoutingCondition(size_fit))
pipe_fitting = element.PartType
# Get routing preference MEPPartId
if pipe_fitting == PartType.Elbow:
print('it is an Elbow')
new_fitting_id = rpm.GetMEPPartId(
RoutingPreferenceRuleGroupType.Elbows,
rc)
part_fitting_id = rpm.GetRule(
RoutingPreferenceRuleGroupType.Elbows,
0)
part_fitting_id = part_fitting_id.MEPPartId
elif pipe_fitting == PartType.Tee:
print('it is a Tee')
new_fitting_id = rpm.GetMEPPartId(
RoutingPreferenceRuleGroupType.Junctions, rc)
elif pipe_fitting == PartType.Cross:
print('it is a Cross')
new_fitting_id = rpm.GetMEPPartId(
RoutingPreferenceRuleGroupType.Crosses, rc)
elif pipe_fitting == PartType.Transition:
print('it is a Transition')
new_fitting_id = rpm.GetMEPPartId(
RoutingPreferenceRuleGroupType.Transitions, rc)
else:
new_fitting_id = None
print('current fitting id: {}'.format(fitting.GetTypeId()))
if (new_fitting_id
and fitting.Id != new_fitting_id
and new_fitting_id.IntegerValue != -1):
fitting.ChangeTypeId(new_fitting_id)
except Exception as e:
print("Fitting error")
print(e)
transaction.Commit()