Profile smoothing with Dynamo & Python


I have been making road resurfacing models in C3D for a while. With my method, the most time-consuming part of them was the smoothing and the finalization of the vertical profiles.

Recently I have been trying to automatize my smoothing method with Dynamo and Python. Unfortunately I am a full beginner in both languages, so the progress is very slow.

Without describing it too deeply I present to you my newest idea, that I would like to reach, and please if you had similar developments or just have some hints, share your thoughts with me.

As base data, I have a supporting profile in C3D, which comes from a scanned survey of the existing pavement. It consists of bunch of PVIs. I want to fit a spline/polynom/polycurve to this supporting profile, then convert this entity to straight lines (polyline) where the minimal section lengths can be defined in each case. The most important aspect regarding this conversion is that the polyline must fit the spline/polynom/polycurve from the upper side, it shouldn’t intersect and go below it.

I have already tried “Profile.PolyCurveByRange” node in Dynamo for converting my supporting profile but it didn’t give a good result. Now I’m trying polynomial regression with NumPy package of Python ([Polynomial Regression in Python - Python Tutorial]). If I get stuck I will investigate the SciPy package as well. Unfortunately for the polyline conversion I have no clue yet.

Hi @denes.nagy

I can get this discussion started as I have done something similar creating a best fit profile tool for low rail track profile design using dynamo (No python though). Unfortunately, I can’t share the dynamo file due to company IP guidelines but I can offer some ideas and suggestions that worked for me during development.

When trying to automate anything really, I find it really helpful to understand the process manually first and have a detailed list of these steps before starting. Once you have this list, you can start breaking up your approach in dynamo based on that list of steps.

For your idea, I assume this isn’t something the best fit profile tool can solve right? The best fit tool didn’t work well for me so this is a workflow I used that you may be able to try and see if it gets you closer to your end result in dynamo using the Civil3DToolkit :

  1. Get all PVIs from your base data profile using ProfileExtensions.PVI node and then compile a list of all the PVI stations using the PVI.Stations node.

  2. Filter and remove PVIs that are too close together to help with the smoothing process. You can try different distances between PVIs to see what works best for you. I went with 5m (~16ft) but this can be an input that can be changed to whatever values works best for your case. I found that too many points too close together can skew the data and hinder the smoothing process down the line. Here is a snippet of this process in dynamo:

  3. After the close PVIs have been removed, gather the elevation and grade in of all the PVIs using the PVI.Elevation and PVI.GradeIn nodes. I ended up exporting this data to excel to help visualize the smoothing in the next steps a bit better but I think it could be done in dynamo as well. It just helped me see the smoothing process in excel rather than in dynamo.

  4. With the data of all the Grade Ins of all the PVIs, I found the change in grade at each PVI (Grade Out - Grade In). The reasoning behind finding the change in grade is that where the change in grades of PVIs are near 0% plus or minus a tolerance, that’s a good indication that section of the profile is tangent. Where there are changes in grade that are greater than your tolerance, that indicates the sections where the profile is in a vertical curve.

  5. This step is where the smoothing begins to take place in Excel in my workflow. With the change in grades throughout the length of the profile, I took a “rolling average” of the change in grades for a couple PVIs before and after each PVIs. This “rolling average” helps to smooth out the change in grade data to begin to understand the data behind the change in grades. Bentley OpenRail uses a similar approach in their horizontal and vertical regression tools. Below is a snippet from the excel that helps to visualize this process and see the smoothing of the data

  6. From here, I used the excel data and the ranges of tangent/vertical curves and imported it back to dynamo to automate the creation of a profile rather than a polyline to try and best fit the profile. There are several nodes in the toolkit to create profiles, add PVIs, add vertical curves etc. You may have to do some experimenting from here if you want to use polylines/3dpolylines. The grade I used for the tangents was the average grade ins in the station ranges of all the tangents determined from the data. I then used the midpoint of the station ranges from the data that were determined to be a vertical curve to get the station of a PVI and continued the grade of the tangents to this PVI station to get the elevation. I went a step further and had dynamo add vertical curves with the curve lengths from the station ranges as well.

I don’t know if this process will work for you completely but it could get you going and give you some ideas. I didn’t have much time or budget to enhance and optimize this workflow. Ideally, I would’ve liked to keep all the data manipulation in dynamo to avoid exporting to excel to import back into dynamo. This did take a lot of time develop but breaking it up into steps helps in the creation of the final product. You may also need to add another step to increase the PVI elevations or use some logic in dynamo to ensure the profile doesn’t intersect or go below the base profile but this does seem doable as well.

Hope this helps! If anyone can add to this or has any other ideas/workflow that I missed, feel free to chime in.


Hi @omar.g ,
Thanks a lot for the detailed description.
I have been also trying a PVI weeding method, similar that you described above, but in my case it is not right way.
You are absolutely right, that I have to understand and figure out the process manually, I’m still in this period unfortunately.
Anyway I get some new impulses from your briefing, maybe the rolling average will be a useful function for me as well. I will keep it in my mind!