Spreading Contour Lines Starting in a Single Plane by a Set Interval

I would like to take the contour lines that I have imported from a pdf file (which means they are all in a single plain) and spread them out by a set interval. If someone can write a python script that would take would allow the lowest and highest contour lines to be selected and then have the interval distance be specified that would save a great amount of time.

Thank you,
William

@William15

It’s spelled plane, not plain…

Hi William -

Not a script, but a way to do this somewhat quickly the manual way:

-wim

I was going to post this before my laptop gave out this morning…

The problem is that in V8 currently, vertical nudge with the PageUp/PageDown keys is broken - and has been for a long time despite my repeated requests to fix it. It seems to work now with simple PageUp/Down, but not with Ctrl+ or Shift+ - which simply zoom the view. So the linked method can sorta work if one makes sure to set the interval as one needs for Nudge without Shift or Ctrl.

It does work of course with the Gumball, just less convenient and more clicking.

Hi Mitch -

That seems to be working as expected here using these settings (in a mm document).

-wim

You must have a later version than me here. It’s not working in SR18 (not SRC). Probably only very recently fixed.

Also not working in the current SRC 8.19.25112.13001, 2025-04-22

I don’t see any indication of this having been fixed in the YouTrack item.

https://mcneel.myjetbrains.com/youtrack/issues?q={nudge}&preview=RH-84974

Works in here with (8.19.25112.13001, 2025-04-22)

Hi Mitch -

I now tested on 8.16 and 8.17 on macOS and that works fine there as well.
You must be running into something else. Does this behave the same across all schemes that you have?
-wim

I’m on Windows… And yes, on all of my computers. Will test on Mac 8.19 in a bit.

My screenshot and first reply were from Windows.
On macOS, I don’t need to uninstall a version to run an older version and I can very quickly go back to all service releases of Rhino 8…

With Fn + Ctrl + Shift, plus the up/down arrows it works here on Mac 8.19 SRC.

However, it is definitely NOT working here on any of the Windows machines I have, US English OS with Rhino running in English, French or German. I also tested on a machine that has an Italian Windows OS but running Rhino in German, same thing.

Only Nudge with no modifier key (no Shift, no Ctrl) works as it should with PageUp/Down.

As I stated previously, the Youtrack item does not say “fixed”.

The first series is with Nudge + PageUp/Down alone. The second is with Shift+, the third is with Ctrl+, and the last again with only PageUp/Down

Looks like we have been on different pages…

From

and

… I assumed that only PageUP and PageDown were being used. Not in combination with other keys.
-wim

From my first post…

I made a tool for this 12 years ago, but it was a mess, so I cleaned it up a bit but didn’t have much time. It can be made smoother, but it isn’t half bad. So please contribute if you like guys.

SortHeightCurvesByLine.py
#SortHeightCurvesByLine.py
#Script written by Holo
#Script version januar 2013 - updated april 2025

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def sort_height_curves(curve_ids, line, dblStart, dblHeight):
        ### DO the calculations in 2D
        ### Project all curves to world XY plane
        plane = rs.WorldXYPlane()
        for i in range(len(curve_ids)):
            temp2Dcurve=rs.coercecurve(curve_ids[i])
            temp2Dcurve = Rhino.Geometry.Curve.ProjectToPlane(temp2Dcurve, plane)
            sc.doc.Objects.Replace(curve_ids[i], temp2Dcurve)
        
        ### Add the line as 2D line (set z values to 0)
        line[0][2] = 0
        line[1][2] = 0
        LineCurve_id=rs.AddLine(line[0],line[1])

        ### Set up an array
        intersectionData=[]
        failedObjects = []
        
        ### Find intersection for all curves
        StartPt=rs.CurveStartPoint(LineCurve_id)
        for curve_id in curve_ids:
            arrIntersects=rs.CurveCurveIntersection(LineCurve_id, curve_id)
            try:
                # Get first intersection point on line
                intersectionPt=arrIntersects[0][1]
                # add distance, intersection and id as list to list
                intersectionData.append ( [ rs.Distance(line[0], intersectionPt),(intersectionPt) , curve_id] )
        
            except:
                # If intersection failed add curve to failedObjects
                failedObjects.append(curve_id)
        
        ### Sort list by distance to startpoint on line
        sortedList=sorted(intersectionData)
        ### Move curves to new position
        i = 0
        for itemList in sortedList:
            rs.SelectObject(itemList[2])
            rs.MoveObject( itemList[2], (0,0,dblStart+i) )
            ### Add height step to i for next curve
            i += dblHeight
        
        rs.DeleteObject(LineCurve_id)
        
        ### Check for failed objects
                ### IF intersetion(s) failed curve(s) are selected, prompt user and return
        if len(failedObjects)>0:
            rs.UnselectAllObjects()
            rs.SelectObjects(failedObjects)
            rs.EnableRedraw(True)
            rs.MessageBox("Selected curve(s) did not intersect with the line.\n!!! They are now projected to World XY plane !!!", 0, "ERROR")
            return
        

def runScript():
    ### Get the curves to sort
    curve_ids=rs.GetObjects("get curves", filter=rs.filter.curve, preselect=True)
    if not curve_ids: return
    ### Get a crossing line for sorting
    line=rs.GetLine()
    if not line: return
    ### Get the start height for the first curve
    dblStart = rs.RealBox("At what height is the first curve at?", 0, "Start Height")
    if not dblStart: return
    ### Get the height steps
    dblHeight = rs.RealBox("What are the height steps?", 1, "Steps")
    if not dblHeight: return
    
    ### Run the script
    rs.EnableRedraw(False)
    sort_height_curves(curve_ids, line, dblStart, dblHeight)
    rs.EnableRedraw(True)

runScript()

And here is a .py file for downloading if you prefer that.

SortHeightCurvesByLine.py (3.1 KB)

1 Like

Thank you for info. I have had some success using the distribution command and setting a distance in the spacing option. I believe that this only works if there is a single peak and trough selected. Curves get jumbled otherwise.

I could not get the script to work.

I am out for beer an music now, so maybe someone else ca take a look?

Hi William -

How are you running this script?
When you run EditPythonScript and copy-paste the code from the collapsed part of Jørgen’s post, it should run.
-wim

Hi @William15
you got it working?