Railings- Auto place by selecting surface

Hello everyone, I’ve been trying to create a script that lets me place a certain railing type around floor slabs/floor openings. So far ive gotten it to place on the levels I want (getting data from an excel file) but it only places it around the slab and NOT the openings.

Anyone have any idea of why it’s not placing around the openings? ANY feedback would help, thanks.

You’ll see the name of the node is Surface.PerimeterCurves - it is doing just that. Getting the perimeter - not the holes. You’ll need to get those separately. And they could be created with the floor sketch - or with the opening tools, or with some other family that cuts a hole.

Ahhh I see, what nodes do you think would for to find those holes in the slabs?

Which Revit version? In 2022, Floors have a SketchID property that points to the sketch used for the floor. Previous versions - you are out of luck. You would have to go through some effort to create some intersecting planes with the geometry and find all the loops.

If it isn’t part of the sketch, but done with the openings, then you need to get the openings. Again - in 2022 - openings have SketchID’s. Previous versions - no SketchID.

Take a look at this thread.

I want to edit the sketch of an existing floor or slab - Revit - Dynamo (dynamobim.com)

thank you aaron i really appreciate your comment.

Not sure if this would be the same as finding holes in the slab tho? But I will take a look!

I think that was added in the Revit 2022 API and the CRUMPLE package by @GavinCrump may have nodes for that.

1 Like

dang, sadly i am currently using revit 2020 & 21

In this case my node just generates fresh floors with multiple curveloops.

@YBMCarlos I’d suggest in this case you get all the edges of the geometry by isolating and exploding the top face. From there archilab had a node that can find all closed loops from a list of curves - can’t recall its name but its something like Curve.FindClosed I think.


thank you gavin! I will take a look at this tomorrow morning. I might just need a fresh set of eyes on things.

1 Like



You can get the faces of a host and then its curve loops:

import clr

import Autodesk
from Autodesk.Revit.DB import *

import Revit

# The inputs to this node will be stored as a list in the IN variables.
floors = UnwrapElement(IN[0])

# Place your code below this line.
floorCurves = []
for floor in floors:
    faceRef = HostObjectUtils.GetTopFaces(floor)[0]
    face = floor.GetGeometryObjectFromReference(faceRef)
    curveLoops = face.GetEdgesAsCurveLoops()
    curveloopCurves = []
    for curveloop in curveLoops:
        curves = [c.ToProtoType() for c in curveloop]

# Assign your output to the OUT variable.
OUT = floorCurves



GroupCurves I believe.

That said, filtering the faces to get the ‘upper’ (use the normal with a Z component greater than 0.25), getting the perimeter curves, grouping those curves (via the Archilab node), offsetting them by [-1,1] * (yourSetbackDistance), and then filtering to just sets which intersect the original surface, and exploding the polycurve is likely the way to go. However you may have some issues with the ‘sanity’ of the sketch in some cases (sloping floors with an opening, etc.)


Thank you for this. I have tried it out but I dont think im properly using the script/ other nodes.

Thanks for this reply Jacob! I am currently having a hard time trying to wrap my head around this since I just started using dynamo a couple months ago but I will be trying my best to understand and apply this into my script. Thanks again!


You must convert the lines to polycurves, I guess.

Before connecting something to the node, first check what’s the right data type to connect into it by hovering the mouse over the inputs of the node.

any idea on how I can covert it to polycurves?

With the PolyCurve.ByJoinedCurves node.

Thank you, I tried everything except that one haha.

But now my issue is still the same essentially. It places it around the slab but not the openings, and this time it only places it n one floor instead of the floors I have set in my excel sheet which is Levels 2-4.

I’m assuming a change in the python script could change this? I don’t know any python sadly but that’s my initial guess.

Jacob, I’ve tried to understand your comment but its a bit tough for me to wrap my head around it. Sorry about that but I’ve gotten the Z points & i tried to grab those but with no luck. Any suggestions on how i can filter those out? Ive tried using the “contains” node but that didn’t help me.

That is not correct - Surface.PerimeterCurves takes the inner loops as well