Script for Floor to Follow Topography

Hi all,

I am trying to build a script that will make a floor follow a topo surface when both of them are selected.

This is the code that I have at the moment but it’s not working.

from pyrevit import revit, DB
from pyrevit import script
from pyrevit import forms

# Function to get the elevation of toposurface at a given point
def get_toposurface_elevation(toposurface, point):
    location = DB.XYZ(point.X, point.Y, 0)
    elevation = toposurface.GetElevationAtPoint(location)
    return elevation

# Function to create a floor at a specific elevation
def create_floor(document, level, elevation):
    floor_type = None  # Set your floor type here
    floor_profile = None  # Set your floor profile here

    floor = DB.Floor.Create(document, floor_profile, floor_type)
    level_param = floor.get_Parameter(DB.BuiltInParameter.LEVEL_PARAM)

    offset_param = floor.get_Parameter(DB.BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM)

    return floor

def main():
    # Prompt user to select a toposurface
    toposurface = forms.select_element_by_category(
        msg="Select Toposurface"

    if not toposurface:

    # Prompt user to select a level for the floor
    level = forms.select_level()

    if not level:

    # Get the boundary points of the toposurface
    boundary_points = toposurface.GetBoundaryPoints()

    # Create floors at the elevations of the toposurface
    with revit.Transaction("Create Floors on Toposurface"):
        for point in boundary_points:
            elevation = get_toposurface_elevation(toposurface, point)
            create_floor(revit.doc, level, elevation)

if __name__ == "__main__":

@rivindub ,

Do you have any Errors and warnings to show?
Which Revit Version do you run?



Hi @andreasd811

I am running Revit 2023.

This is the error that I’m getting.


@rivindub ,

looks like a external library it is function, seems to be it is not imported.
do you want select a element or several elements by selection? or rectengular selection ? and only one category?



I’ll help you analyze that error report.
You basically do these 2 things for most of the errors you encounter.
I’ve used some OCR to convert your image to text, so there’s some serious garbled text in there , but the points are the same

Step 1, look at the top paragraph of the traceback (Most of the time the essential error info is contained here)
So we want to look just at the IronPython Tracback

IronPython Traceback :
Traceback (most recent call last):
"C : \Users RivinduB \digitaldes ign. extens ion\digitaldes ign. tab\WIP. panel \C01umn1. stack
line 52, in <module>
"C : RivinduB \digitaldesign. extens ign. tab\WIP. panel \C01umn1. stack
line 27, in main
AttributeError: •module • object has no attribute 'select_element_by_category•

Step 2
Read that traceback from bottom to top
The traceback is printed in ‘order of execution’ by python.
Each line is a step in the python execution up until you encountered the error. The last line is usually the line containing the error.

Step 3
Identify the issue by looking at what the bottom line says. In this case it says

File C:\.....\Column1.stack\yourscriptname.pushbutton\ line 27, in main
AttributeError: 'module'object has no attribute 'select_element_by_category

There’s some usefull info in here.
1st. It says which python file of your script is causing the issue.
2nd It says that at line 27 in your file (in def main ) an error has occured
3rd It says that it’s an attribute error. You are asking for select_element_by_category, but the module does not know a function called that.

So put those together and it means that you are calling a pyrevit function from froms that does not exist.

When walking up through the traceback, you sometimes get errors inside modules that you didn’t create or write. In those cases it’s best to skip those lines and keep going up right until you find a point in your own code where the error messages begin.


check this

the forms module does not have such a method select_element_by_category() (It feels like an hallucination from chatGPT :stuck_out_tongue: )

but only these methods:
pick_element_by category()

Is this a ChatGPT script? There seems to be a lot of funky things with this code, like I can’t find any method for toposurfaces call GetElevationAtPoint(). and also it looks like the code is attempting to make a new floor for every point? You shouldn’t even be creating a floor if you want it to match an existing one to the topo.

I’ve done something similar to this, and it not a simple feat.

I think this would be the layout of the script:

  1. Get floor and topo
  2. Get points of floor
  3. Project those points up to intersect with the topo.
  4. Edit the floor shape to move the points to the new locations.