Relative paths

In the Hops component, is it possible to specify the path to the definition as relative to the current file location?

Absolute paths would be a nightmare, e.g. when copying a project to another machine or simply when renaming the containing directory.

In a reply to another question, @AndersDeleuran showed me how to get the path of the current script. That allows the construction of relative paths: (10.8 KB) (2.3 KB)

Personally, I find that a much more robust solution compared to specifying absolute paths.


thanks for sharing :ok_hand:

Aside from ghenv.Component.OnPingDocument().FilePath you could also use ghenv.LocalScope.ghdoc.Path. Same result, just an alternative.

import os
if definition:
    root = os.path.dirname(ghenv.LocalScope.ghdoc.Path)
    path = os.path.join(root, definition + ".gh")

New version! This one works from within clusters: (9.1 KB)

Thank you, that works great from the main document! But not from within clusters: (3.9 KB)


Clear, thanks for letting me know!

Up untill now I haven’t had the need of using a cluster. Mostly I resort to ghPython/C# within grasshopper or just writing a plugin if I use something repetitively.

Unfortunately, as I found out yesterday, with clusters, it all blows up when actually renaming the containing directory. See my reply in the thread Hops is missing inside some clusters.

May I ask why you want to use a hops component?
Also what rhino version are you using, rhino 8 I assume from the other post?

Yes, Rhino 8. I put a lot of definitions now in Hops. Asides from lack of support for relative paths and another quirk, I enjoy Hops. They allow me to split a complex definition into sub definitions. These Hops functions can be thoroughly tested. By comparison, clusters feel fragile. But they have their place too.

A nice side effect of Hops is caching. This makes it possible to try a complex definition with different sets of values and quickly jump back and forth. I have not yet looked into background execution, but that looks nice too. Also uploading Hops to a fast server is an attractive option. But, yes, Hops still feels a bit rough around the edges.

After a bit of Python, I think I’m back to absolute paths, not ideal though: Update absolute paths

I see,

Perhaps interesting as an alternative (in case caching isn’t a hard requirement), is to write the complex definitions as seperate .gha component. Rhino 8 made it quite a bit easier to write custom components, where you previously had to go to VsCode and use the C# template.

This post has an example video in the beginning: see here for an example…

In the case above you won’t be required to provide paths either. As it’s just another grasshopper component. The main concern would be ensuring that the user has the right version of plug-in installed to run said definition.

Thanks, but that’s a much more heavyweight solution.

With Hops, every component is just a Grasshopper script that I can open by its own and test thoroughly. Normally I have a bunch of input data for testing that I can quickly connect, and I keep that data right inside the GH file. Hops allows me to write complex definitions and split them up into many small ones. That’s somewhat like procedural programming. Some of these Hops functions may only have a few grasshopper components, maybe only a single mathematical expression that needs good testing. They are very project specific, and they may change from version to version of the same project. Hence, I don’t want to have them in a global place. Instead I keep them with each version of a project in the same directory.

But I’m digressing. This thread is about relative paths, and I hope they will soon be available.

Success! Moving the detection of the containing directory to the top level solves the issue. Now the Hops components in the clusters don’t get lost after renaming the directory. I hope that this solution is stable. (14.4 KB) (2.3 KB)

Another update, the trick to rename containing directory A into B as follows:

  1. Copy A to B.

  2. Open B\ First it will first reference all Hops functions from A. Then it will update to take the Hops functions from B. If it cannot first find them in A, then they will get lost.

  3. Save B\

  4. Delete A.

That means, my above [solution][1] doesnt’ really add an improvement. It only worked because I didn’t actually test renaming the containing directory. Instead, I copied it to a new place on disk, leaving the old directory where it is. Therefore, the Hops functions could always be found.