Problem creating second level of stairs via Python/Dynamo

When trying to create stairs (sketched run method) at a level other than Level 1 (0’- 0" elevation), they appear at an entire level higher than what it should be. Even though the floor to floor height and riser number is exactly the same, I get the error message:

“Stair bottom end exceeds or cannot reach the base elevation of the stair. Add/remove risers at the bottom end by control or change the stair run’s “Relative Base Height” parameter in the properties palette.”

Looking a the Relative Base Height in Revit for each run, they are exactly as expected, but the actual stairs are one level higher:

The stairs created first (shown here on Level 1) had no errors. Only when I adjusted the Levels (“Base” Level 2 and “Top” Level 3) does this behavior occur.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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 *
from Autodesk.Revit.DB.Architecture import StairsRun
from Autodesk.Revit.DB.Architecture import StairsLanding
from Autodesk.Revit.DB import CurveLoop

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

doc = DocumentManager.Instance.CurrentDBDocument	
class StairsFailurePreprocessor( IFailuresPreprocessor ):
	def PreprocessFailures(self, failuresAccessor):
		return FailureProcessingResult.Continue

baseLevel = UnwrapElement(IN[0])
nextLevel = UnwrapElement(IN[1])
b1Curves = IN[2]
r1Curves = IN[3]
p1Curves = IN[4]
b2Curves = IN[5]
r2Curves = IN[6]
p2Curves = IN[7]
elCurves = IN[8]

TransactionManager.Instance.ForceCloseTransaction()

newStairsScope = StairsEditScope(doc, 'New Stairs')
newStairsId = newStairsScope.Start(baseLevel.Id, nextLevel.Id)

trans = Transaction(doc, 'Add Runs and Landings to Stairs')
trans.Start()

bdryCurves1 = list(b1Curves)
riserCurves1 = list(r1Curves)
pathCurves1 = list(p1Curves)

bdryCurves2 = list(b2Curves)
riserCurves2 = list(r2Curves)
pathCurves2 = list(p2Curves)

landingLoop = CurveLoop.Create(elCurves)

r1Count = len(r1Curves)
r2Count = len(r2Curves)

newRun1 = Autodesk.Revit.DB.Architecture.StairsRun.CreateSketchedRun(doc, newStairsId, baseLevel.Elevation, bdryCurves1, riserCurves1, pathCurves1)
newLanding = Autodesk.Revit.DB.Architecture.StairsLanding.CreateSketchedLanding(doc, newStairsId, landingLoop, newRun1.TopElevation)
newRun2 = Autodesk.Revit.DB.Architecture.StairsRun.CreateSketchedRun(doc, newStairsId, newLanding.BaseElevation, bdryCurves2, riserCurves2, pathCurves2)
trans.Commit()
newStairsScope.Commit(StairsFailurePreprocessor())

OUT = newStairsId

StairsAndLandingImport!!.dyn (111.1 KB)

I got some great help previously, so hopefully this won’t be much of a challenge.
Previous Topic

To be clear, the number of risers are correct. Just the level has changed. Also, this issue occurs with or without a previous successful run (at Level 1).

Any help is greatly appreciated.

Thanks,

LoRue

1 Like

Additional Info:
Doing a Snoop, the Base and Top Elevation are correct, but the bounding box is one level higher:

What is going on?!?!

Hello @LoRue
for create next levels you can use MultistoryStairs Class

import clr
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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 *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB.Architecture import MultistoryStairs

from System.Collections.Generic import SortedSet

#Preparing input from dynamo to revit
stair = UnwrapElement(IN[0])
lstnextLvl = UnwrapElement(IN[1])
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
multiStairs = MultistoryStairs.Create(stair)
for lvl in lstnextLvl:
	setLvlId = SortedSet[ElementId]([lvl.Id])
	multiStairs.ConnectLevels(setLvlId)

TransactionManager.Instance.TransactionTaskDone()

OUT = multiStairs
2 Likes

Hi @c.poupin , I may not have explained the issue properly.

My run needs to start on Level 2 (or any chosen level). I can do a workaround where you create it on the 1st then move it by hand later, but what fun is that? :grinning:

Can your “create Stair” script start on Level 2? If so and it’s the same as mine, something else is causing the error, no?

Thanks,
@LoRue

Hello
I confirm that I am getting the same problem, strange… :roll_eyes:

@c.poupin
Aha! Thanks for confirming on your end.
So how can we narrow down the issue? I have not seen anything in the API docs that places restrictions on stair level placement. Using a fresh Revit project does not work, nor does plugging in actual elevation numbers into the script.

Are you getting the same error?
“Stair bottom end exceeds or cannot reach the base elevation of the stair. Add/remove risers at the bottom end by control or change the stair run’s “Relative Base Height” parameter in the properties palette.”

Does the stair level show correctly in properties, but not visually?
If you use Snoop, do you see that it’s on the correct level, but the bounding box relates to where it actually is placed (see my screenshot )?

Surely this is not a bug, or is it???

Thanks,

LoRue

yes, same error :roll_eyes:

yes, need to change the base level (lower level) in properties to fix location

Maybe a problem with elevation geometry lines

@c.poupin:
When I lower the base level in properties, it only looks correct. For a Level 2 stair, you have to set the base to Level 1, even though it visually looks like it’s on Level 2.


Using Snoop, the bounding box still shows the range of Levels 3 and 4 !

When you try and make a multi stair:

I am not clear on what you mean by “elevation geometry lines”.
The imported CAD lines are Z==0. It doesn’t seem to matter which level the lines are imported to. Reversing the line direction only creates a mangled stair.

Is the only way to do this is to create at Level 1 and move up?

Here is the answer: The newRun1 line should be this:
newRun1 = Autodesk.Revit.DB.Architecture.StairsRun.CreateSketchedRun(doc, newStairsId, 0, bdryCurves1, riserCurves1, pathCurves1),

For some reason, the baseLevel.Elevation adds to itself, so you replace with a 0.
That’s it ! Someone answered my similar post on Stackoverflow, and this closes the circle.

2 Likes