I have linked cable trays and cable trays with fittings and I want to identify runs of the cable trays, or at least get the straight sections (separated by a bend) in separate lists. Ideally these would be ordered in sequence as they are connected, so I can treat them as a single line that I can create points over i.e. a point at every X distance.
Currently trying the MEPover Elements in connected network node but the elements are returning null. The elements are LinkElements from Bimorph Nodes if it is relevant.
Thank you for help @sovitek I tried your method and have the following results which I will try to modify further to suit what I need. But I was wondering how did you choose an appropriate margin for the Geometry.GroupByDistance node?
This is okay, however, I also have some instances of cable tray fittings that form part of the cable tray run. I notice these are represented by points rather than lines/curves. Would I instead have to look at start/end points and try to figure it out that way?
Hi @Grace.8Y72Z yeah many things can go wrong depends you could try something here and see if it could be better…you are welcome to share a sample rvt we can test on…but will probably not work on random projects…
Thank you @sovitek for your help! This way works well for my project, as well as for this small sample Revit file which includes cable trays as well as fittings. They are solids though so I’ve given it a few attempts but not sure how I would get points (XYZ) along each separate run. I will continue trying and can hopefully update with a solution later …
Hi @sovitek, this is what I was after - thank you! For use in my project, I used AI to edit the code slightly as I was having some trouble with the MEPModel attribute error. Also included the input element in the output list too i.e. if a single cable tray has no connections/fittings, the single cable tray will still be in the output list. Thanks again
import clr
import sys
pyt_path = r'C:\\Program Files (x86)\\IronPython 2.7\\Lib'
sys.path.append(pyt_path)
import System
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
import collections
linked_docs = [doc]
for link in FilteredElementCollector(doc).OfClass(RevitLinkInstance):
linked_doc = link.GetLinkDocument()
if linked_doc:
linked_docs.append(linked_doc)
if isinstance(IN[0], list):
connector = UnwrapElement(IN[0])
toggle = 0
else:
connector = [UnwrapElement(IN[0])]
toggle = 1
bool = IN[1]
def getElementFromAllDocs(element_id):
for linked_doc in linked_docs:
try:
element = linked_doc.GetElement(element_id)
if element:
return element
except:
continue
return None
def nextElements(elem):
listout = []
if isinstance(elem, Connector):
conn = elem
for c in conn.AllRefs:
if c.Owner.Id.Equals(elem.Owner.Id):
continue
elif isinstance(c.Owner, MEPSystem):
continue
else:
newelem = getElementFromAllDocs(c.Owner.Id)
listout.append(newelem)
return listout
try:
connectors = elem.ConnectorManager.Connectors
except AttributeError:
connectors = elem.MEPModel.ConnectorManager.Connectors if hasattr(elem, 'MEPModel') else []
for conn in connectors:
for c in conn.AllRefs:
if c.Owner.Id.Equals(elem.Id):
continue
elif isinstance(c.Owner, MEPSystem):
continue
elif c.Owner.Id.Equals(ownerId):
continue
else:
newelem = getElementFromAllDocs(c.Owner.Id)
listout.append(newelem)
return listout
def nextElementsWithOwner(elem):
listout = []
if isinstance(elem, Connector):
conn = elem
for c in conn.AllRefs:
if c.Owner.Id.Equals(elem.Owner.Id):
continue
elif isinstance(c.Owner, MEPSystem):
continue
else:
newelem = getElementFromAllDocs(c.Owner.Id)
listout.append(newelem)
return listout
try:
connectors = elem.ConnectorManager.Connectors
except AttributeError:
connectors = elem.MEPModel.ConnectorManager.Connectors if hasattr(elem, 'MEPModel') else []
for conn in connectors:
for c in conn.AllRefs:
if c.Owner.Id.Equals(elem.Id):
continue
elif isinstance(c.Owner, MEPSystem):
continue
else:
newelem = getElementFromAllDocs(c.Owner.Id)
listout.append(newelem)
return listout
def collector(elem):
cont = 0
elements = nextElements(elem)
lookup[elem.Id] = elem # Include the original element in the lookup dictionary
for x in elements:
if x.Id in lookup:
cont += 1
else:
item = getElementFromAllDocs(x.Id)
lookup[x.Id] = item
collector(x)
if cont == len(elements):
return elem
def collectorWithOwner(elem):
cont = 0
elements = nextElementsWithOwner(elem)
lookup[elem.Id] = elem # Include the original element in the lookup dictionary
for x in elements:
if x.Id in lookup:
cont += 1
else:
item = getElementFromAllDocs(x.Id)
lookup[x.Id] = item
collectorWithOwner(x)
if cont == len(elements):
return elem
listout = []
if bool:
for x in connector:
lookup = collections.OrderedDict()
collectorWithOwner(x)
listout.append(list(lookup.values()))
else:
for x in connector:
lookup = collections.OrderedDict()
if isinstance(x, Connector):
ownerId = x.Owner.Id
else:
ownerId = x.Id
collector(x)
listout.append(list(lookup.values()))
if toggle:
OUT = list(lookup.values())
else:
OUT = listout