Batch arrowheads

Hi there,

Im working on a project where I want to show the watershed direction of many curves.

I have drawn all the curves manually from highest point to lowest point to indicated downhill.

In Adobe programs, you can give the curve an arrowhead at the ends of a curve.

To have a command or GH component which allows arrows to be added at select ends or both ends, and even a bake component would be very useful.

FabTools for GH was an old component for Rhino 4 and 5, but I’m not sure if it works with 7. It had the ability to bake arrows.


Hi Jeremy - this Python that will add arrowheads to the ends:

import rhinoscriptsyntax as rs

ids = rs.GetObjects('Select curves for arrowheads', 4, preselect=True)
if ids:
    for id in ids:
        rs.CurveArrows(id, 2)


1 Like

Hi Pascal, thanks for this :slight_smile:

I played with the script and can choose for the arrow to be at the start or the end.

As I don’t know python yet, is there a way for arrows to appear at both ends?

Batch remove arrows would be just as useful.

Lastly, is it possible to bake the arrows for control when printing?


Here’s my version - checkboxes for start or end choices (check both boxes for both ends). Saves previous choice within a session. (1.1 KB)

However, they remain screen space objects there is no current way to “bake” them into a curve or hatch. I seem to recall having written a script to make geometry arrows in the not-to-distant past, but I can’t find it right now… Weird.

Ahh - here.

I guess I was working on my other machine and as they are sort of test scripts, they did not get added to my main script library…


Wow, thanks so much for these… this saves a lot of time :slight_smile:

The AddCrvArrowheads is ideal allowing the selection of each or both ends. Does it also allow the batch removal of arrowheads? If so, I can’t seem to make that work.
In combination with scaling the arrows in the print output, this is a good solution.

The add geometry arrow is also good, but perhaps could be improved in a couple of ways; some of which you’ve mentioned.
1 Ability to create geometry at each or both ends
2 Ability to perform action on more than one curve at once
3 Option to fill with hatch
4 Different arrow styles


I dredged up and finished (maybe) an arrow tool I had lurking at the bottom of the pool for a while now - just in case it helps - it might just be uselessly complex - bunch of options, practically an entire arrow management suite. (5.0 KB)

Toggle mode toggles as you go and Absloute mode takes a multiple selection and does them all at once.

To use the Python script use RunPythonScript, or a macro:

_-RunPythonScript "Full path to py file inside double-quotes"


1 Like

No, forgot to do that. Here is an arrowhead remover. Works like the ‘adder’. (2.1 KB)

Yes, that is actually quite a bit of work, I’ll look into it later, items 1-3 shouldn’t be too hard, but 4 (different styles) probably not any time soon. Also, once the geometry arrows are added, they are not so easily removable as the standard arrows - they are no longer object attributes, they are real geometry and to keep track of them would mean storing their info on the curves themselves and being able to retrieve it later.

1 Like

Thank you for this script; remove arrowheads script works great :slight_smile:

Definitely understand about the Geometry arrows, and their management requirement. The ability to bake them to layers is beneficial for management.

For regular arrows, is it possible to give them model space dimensions instead of screen rendering dimensions? Or the option for this? I’m not sure how it works, and probably isn’t possible.


Great script Pascal; super handy. If only it incorporated the ability to remove arrows? Or is this better as a separate script?


Curve arrowheads are pixel-based like Dots - they are simply drawn directly to the computer screen and as such always face the viewer and their size remains constant regardless of the zoom level. Therefore you can’t really give them “model-space” dimensions.

There have been requests for arrows and dots that scale with the zoom level, but that hasn’t been implemented yet AFAIK.

1 Like

Hi Jeremy - to remove, either use the Toggle mode or set the ‘AddArrowTo’ to None.


1 Like

Try this out… (4.0 KB)


Hi Pascal, thanks heaps; I didn’t initially see this as it’s in Absolute mode.

What is the toggle mode use for?
The Mode Toggle only seems to allow singular curves as the input, and not multiple.

This is a super useful script for me; much appreciated.


Thanks Mitch, this will be assigned to a shortcut.


Toggle means you click on a curve at a time and it toggles, I hope, what ever AddArrowTo setting you have. If on End and you click a curve that has an arrow at the end, the arrow goes away and vice versa.


1 Like

Hey Pascal, been using these scripts a fair bit and they are super helpful.

One suggestion with the Arrower script is the following.

When you run the script, it deselects the current selection, and asks for input curves.

I can’t seem to select groups which I’ve made, or easily select by other selection commands etc.

Is it possible for the script to run on the current selection without deselecting and asking for a new selection?


Hi Jeremy - I think in Absolute mode it accepts pre-selection, no? I’ll take a look - If not, I’ll fix it.


1 Like

Hi Pascal, thanks for the advice.

I’ve just done a bit more testing.
If you have a selection of curves, then run the script, it will apply the arrow settings which were used last time the script was run in absolute mode.

To change the settings, I had to deselect, run the script, set the desired settings, enter;
then select the group, and finally run the script with the preset settings.

A more intuitive experience might be this.
Make the selection of curves, then run the script, choose the options (perhaps with live preview), then press enter
If no curves are selected, then the user is prompted, but can select groups etc.


Hi Pascal, does the script work in grasshopper? I can’t get it to work. Thanks

Hi Patrick -

As far as I can tell, all scripts that were shared in this thread are meant to be run in Rhino, not Grasshopper.