Loop until all Source Elements in the list are original Walls

Hi can anyone help me tweak this Part.SourceElement script to be able to loop until all the elements in the list are Walls?

Currently if a Wall is turned in a Part then the source element would be the Wall but if the Part is then divided into several Parts then the source element would be the first Part that is converted from Wall. I want the script to be able to list the first original Walls. Thanks


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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

items = UnwrapElement(IN[0])
elementlist = list()
for item in items:
    sourcelist = list()
    for source in item.GetSourceElementIds():
        sourcelist.append(item.Document.GetElement(source.HostElementId).ToDSType(True))
    if len(sourcelist) < 2:
        elementlist.append(sourcelist[0])
    else:
        elementlist.append(sourcelist)
OUT = elementlist

Are you just after the original walls? Or are you after a structured list with both walls and parts?

Maybe you can work with the following? It will return only the original wall elements.

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
#Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

#Import ToDSType(bool) extensions method
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

#Reference the active Document and application
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
items = UnwrapElement(IN[0])

"""
elementlist = list()

for item in items:
    sourcelist = list()
    for source in item.GetSourceElementIds():
        sourcelist.append(item.Document.GetElement(source.HostElementId).ToDSType(True))
    if len(sourcelist) < 2:
        elementlist.append(sourcelist[0])
    else:
    	elementlist.append(sourcelist)
"""
elemIds = []

for i in items:
	pm = i.PartMaker
	sourceIds = pm.GetSourceElementIds()
	for source in sourceIds:
		hostId = source.HostElementId
		elemIds.append(hostId)

uniqueIds = set(elemIds)

OUT = [doc.GetElement(i) for i in uniqueIds]

Your script still spits out the same outcome. The parts that have been split into more parts will have the part that is split from as the original element. I’m after the first original wall before it is turned into a part.

I see the challenge now :slight_smile:

The script below should work, if a part is devided into another part. But! I don’t work with Parts, and therefore unaware if you divide parts multiple times. If this is something you do, then setting up a recursive function is probably a much better solution for this.

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
#Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

#Import ToDSType(bool) extensions method
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

#Reference the active Document and application
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

items = UnwrapElement(IN[0])
hostWalls = []

for i in items:
	pm = i.PartMaker
	sourceIds = pm.GetSourceElementIds()
	for source in sourceIds:
		hostId = source.HostElementId
		hostElem = doc.GetElement(hostId)
		cat = hostElem.Category.Name
		if cat == 'Parts':
			sids = hostElem.PartMaker.GetSourceElementIds()
			for i in sids:
				hostWalls.append(doc.GetElement(i.HostElementId))
		else:
			hostWalls.append(hostElem)

OUT = hostWalls

image

1 Like

Hi @MartinSpence the script works if you split it once but if it is being split again and again, it will still spit out the original part.

Yep, thats what I described in my last post :slight_smile:

That’s why I said a recursive function is probably the solution you are after, but I can’t help setting that up today.

hello, try this?

import clr
clr.AddReference("RevitNodes")
import Revit
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager 

clr.AddReference("RevitAPI")

import Autodesk 
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument

parts = UnwrapElement(IN[0])

def get_original(part):
	run = True
	while run:
		source_ids = part.GetSourceElementIds()
		source = doc.GetElement(source_ids[0].HostElementId)
		if not isinstance(source, Part):
			run = False
			return source
		else:
			part = source

output = []
for p in parts:
	output.append(get_original(p))

OUT = output

Thanks @newshunhk, the script worked just how I wanted it thanks!

1 Like