Creating a path along surface that always decreases in z value?

Hello everyone, I have a very complex topography, in the form of a mesh, but supposing I could patch the contour curves and generate a surface, are there any resources out there that do what I stated in the title? And if not, a hint on where to start would be of great help.

Ideally I would pick two points on the surface, or even contour lines. A, B, and generate a polyline that connects successive points that are always below the previous point. The idea is that this line will be a canal of water that travels because of gravity, hence the slope can never be positive.

To clarify, I am not talking about flow lines, I am talking about a single polyline. If the possibilities to go from A and B with ever decreasing height path, then the shortest or longest criteria could be used to pick the points.

If I remember right, in this thread were a few solutions with shortest path, maybe it helps.

Easy with code (you can have that with a mesh as well).

BTW if memory serves well there’s an Anemone - very slow - solution around for drainage paths [I can’t recall the thread name].

Post your topo thingy for tests

Hello Peter,

Yeah, no suprise haha.
I think this is the thread you are referring too.

Could not make any use of the things in there.

There is also this one, I think the word “Gradient Descent” describes the problem well.

My topo is huge actually, I just hope and pray that a method applied to a generic topo can also work one mine.


Anyway found the Anemone thingy. Logic is very simple (try it with a mesh: if it works it could be 1M times faster VS a nurbs). (22.3 KB)

For the Dark Side:

  1. Spread points (or just one) along a mesh (avoid nurbs stuff: slow, avoid short paths: VERY slow) . Sample them in a DataTree (each on a branch).
  2. Create a Recursion: for each last Point per branch move point and get the closest. Check Z: if is rising mark that branch as terminated, if not add the closest. If the mesh has a gazillion faces and they are “even” in describing the terrain play ball solely with face centers.
  3. Recursion terminates if all branches are marked as terminated (or use some other condition).
  4. Using the points per branch do your polylines

Thank you, I think I have that one, on my phone right now.

I am not after dreinage paths though. Although tecnically, you could consider what I am after as one single dreinage path, where you can pick Start and End.

Thanks Tim, that looks promising with lots of material, will check on it.

Found a very old C# thingy made a million years ago.


  1. your mesh is a pro thingy (huge AND detailed AND “even”),
  2. you don’t care about great accuracy (who cares?),
  3. you like speed (who doesn’t?) …

… this captured thingy is for you: working on Mesh face centers (Recursion does an int DataTree meaning that is lighting fast) and yields results in a few milliseconds no matter the size of the Mesh (you can triangulate it if you want). There’s 2 other far more accurate methods/options available as well (but why bother?)

Sterile start points are things that have no adjacent Faces with a center with lower Z.

1 Like

Thank you Peter, that looks very good, can you pick an end and a start point though? That would be ideal.

This works via random points (face centers) sampled from the centers List … or the centers that are above some drainage level (an user option that one).

Other than that … you mean in fact 2 points (both start) since the end is the lowest (Z) face center achievable/possible (meaning that going from a given start to a given end is rather ambiguous).

Or you want to connect the start (if not sterile) to some end (ditto) VIA some low point (if this connection is possible at all).

Or you want to use a start, then find the low point (if start is not sterile) and then find N other start points that end to the very same low point?

BTW: 100 milliseconds for 100K faces and 500 start points. Maybe // stuff can cut the mustard way better (but why bother? that’s the 1M question). Wait … what an idiot: marking a recursion branch as fixed (if a low point is found) could greatly boost speed. Like this:

Hmm … the Ducati (fast and rouph) way is not bad … but some times (tri meshes) yields a bit kitsch (or “funny”) paths:

On the other hand with regard the Harley Davidson way (VERY slow and “accurate”) … well … here’s the issue:

Imagine a given last point (per recursion branch). If we move that (-Z) and then attempt to find the Mesh Closest thingy (the Anemone example does that) then we’ve got freaky (and VERY slow) results IF there’s steep and flat mesh faces around (and the mesh is huge and this and that).

Enter a different approach: from each last point we intersect the Mesh with some standard Mesh (from a Sphere with a given search radius) get the ccx lines, get the points at start, sort the List and test if the lowest (Z) point is lower than the start. That yields evenly spaced polypoints regardless the slope (Note: is 15++ times slower) … BUT … the paths MAY not share a common point as they descend towards Nirvana.



1 Like

Thank you for your time Peter.

I am not sure I am following, in most of your screenshots there are multiple paths, when I am just looking to find one, picking a start and end point on the mesh. This start and end point are meant to be connected with a path that always has a negative slope, meaning every successive point should be below the one before.

The rules or parameters I thought are as follow:

-If connection not possible up to end point, run until it is.
-If multiple points are candidates, I imagine the criteria should be to choose the closest, or the furthest point. (I don’t really care)
-Additional criteria could be added such as “maximum segment length” or “maximum slope of each segment”

This image is not literally what I am after but helps to show the idea. (path algorithm to find the shortest, flattest paths between two points)

Indeed my stuff does classic drainage (as fast [and rough] as possible) and it’s not what you want.

For your case a custom Method is required and maybe a totally new C#. Working (obviously) with meshes excludes stuff the likes of Surface short paths (very slow anyway).

A job for the w/e then (but there’s MotoGP AND F1 races around meaning … er … hmm … ).

Moral: Que Será, Será