I am trying to get the subelements from a multistorey stair. This should be possible by getting the stairs ids from the GetAllStairsIds method and then calling Element.GetSubelements to get the stair subelements. I though this Python script would work but I am getting an error message. Any ideas as to how to do this?
import clr
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
str1 = []
str2 = []
mstr = UnwrapElement(IN[0])
stid = mstr.GetAllStairsIds()
for i in stid:
str1.append(doc.GetElement(i))
str2 = str1[1].GetSubelements()
str3 = []
for j in str2:
str3.append(j.UniqueId)
OUT = str3;
The error is:
Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
Traceback (most recent call last):
File “”, line 24, in
IndexError: index out of range: 1
According to your error message, I believe it is because you are calling str1[1], but since you are only feeding it 1 stair, you would need to call str1[0].
That doesn’t work because .GetSubelements is already a method that was not finished (it is missing the ‘()’ ), so you cannot call a method on top of a method. Try making a new variable str3 = str2.ToDSType()
What is interesting to me is that I don’t even get results for the s.GetSubelements() method, but get the individual stairs in the first go. What version of Dynamo are you using?
Thanks. I tried a few different way (not sure of the syntax) but kept getting the same error: List[Subelement]’ object has no attribute ‘ToDSType’. Any ideas
I’ve tried it in Dynamo 2.0 and 1.3.3 with Revit 2019 and I can get the DB elements. GetSubelements I think is new to Revit 2018. Are you using an older version?
This post talks about a bit about how I got to this point. I am bascially automatting stair documentation. So take a stair(s), get its risers/landing and create dimension, tags, number systems, etc. It is all working except for if it is a multistorey stair. I need to be able to get the typology of each substair.
I tried with both Id and UniqueId and both returned the error: AttributeError: ‘list’ object has no attribute ‘UniqueId’
"
import clr
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
str1 = []
str2 = []
str3 = []
mstr = UnwrapElement(IN[0])
stid = mstr.GetAllStairsIds()
for i in stid:
str1.append(doc.GetElement(i))
for s in str1:
str2.append(s.GetSubelements())
for t in str2:
str3.append(str2.UniqueId)
OUT = str3, str2, str1, stid
";
I found the unique Id of it, not quite sure how to look up the element using it. SubElements do not have a normal Id. The problem was that getting a subelement puts it inside of a list, so it isn’t enough to just call a method on it but you have to dig one list deeper before you can:
str3 = []
for s in str2:
for j in s:
str3.append(j.UniqueId)
put that at the end of your code to get the unique id or to use any of the other methods/properties.
And SubElements do not have ToDSType() so need to find another way.
According to your post you got the Unique ID of the subelements, and the DS in that imagr converted the GUID to Element. I assume that can be used for the GUID of the subelements as well.
import clr
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
str1 = []
str2 = []
str3 = []
mstr = UnwrapElement(IN[0])
stid = mstr.GetAllStairsIds()
for i in stid:
str1.append(doc.GetElement(i))
for s in str1:
str2.append(s.GetSubelements())
for s in str2:
for j in s:
str3.append(j.UniqueId)
OUT = str3, str2, str1, stid
Not sure what to do with that and how I can get geometry from it. Topology.Faces doesn’t work on db.subelements.
I think I have solved it. Tried topology.faces on the elements and even through they are the same element (and Id), it return all of them?! Don’t understand why but it seemed to have worked!
This appears to be all you need to get the stair element, from which you can get the topology (as one long list)
stid = mstr.GetAllStairsIds()
for i in stid:
str1.append(doc.GetElement(i))
But if I try to get the landings and stair runs, it still revers back to the main elements which has been copied up into the multistorey stair. I really need to be able to identify the stair run and landing elements within the multistoreystair, otherwise it will be impossible to sort all the surfaces into any logical order
That would only solve part of the problem. I need the individual elements (landings, stair runs, etc) to be able to tag, create number systems, etc. Dimensioning is only one part of it. So we need elements, not just surfaces.
So it’s back to the problem of what to do with the db.subelements. What are they and how can they be used? It isn’t really clear from the documentation.