Text displaying the z coordinate

I was trying to link a text to its own z coordinate, but it seems that it need to be linked to a point.
I thought great I create a point and link to it. It worked!
But then I copied the group and the text continued to link to the original point, clearly beating the purpose.
I have to place about 50 of these and I would rather not to have to edit and click all of them. Actually, it is about 7 clicks for each of them.

I also tried a block (which would be even better), but also did not work.

Since I am here, I would also like to add 750 to the actual z coordinate because the project is in “relative” altitude, but I moved the model closer to zero to avoid (the) other problems with large distances.

Thanks, N

Hi N - see if this quick and dirty go at it does anything good - note it does not update if you move text - if that is needed, we’ll need to adjust.
TextZ.py (656 Bytes)

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

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


Hi Pascal,
Thank you so very much. This was a life saver last night.
Of course, if it would update when moving the text, it would be even better. :smiley:.
Ideally, it would be inside a block (similar to autoCAD) with a symbol for the height, and would export perfectly to AutoCAD… wishes…

But for what I needed yesterday was perfect. Much apreiated.

Hi Pascal,
I am not familiar with Python and it has been more than a decade since I did RhinoScript.
I was able to edit the script so that it would check a text key that I created with the documents real elevation. It works fine.

But I would like to ask you a quick help if it is not too difficult.
Can we run options on the command line (as if it is a native command)?

I would like to set a key for the document (instead of for each text) called “Document Elevation”.
When I Run the script I would like that on the command line appears:
Select Texts (Document Elevation is ###, _Change):
If it is void use 0 for doc elevation, otherwise the user can change and give a value that gets stored on a (new) doc key.

Too complex?

You will get the automatic updates if you use PointCoordinate text field.

  1. Make point object.
  2. Make text in the same place as the point.
  3. Select the text.
  4. Click text fields icon in the Properties Panel.
  5. Click PointCoordinate, turn off X and Y, select point object.

Hi N - please PM me with what you have so far. Yes it is possible to add command line options.


Hi Andrew
Thank you. If you see my first post I mentioned that, but it is not practical because when copying that group the text remains linked to the original point. And each relink are six or seven mouse clicks (I haven’t tried it if it’s on the command line but that would be at least a couple). When you need to place several tens of height texts it is just not practical.

is a grasshopper solution an option? Here i deconstructed the points and added 750 to the Z.

requires elefront 4.3
Re_pointsValues.gh (11.3 KB)

Hi Pascal.
Last night, all I did was to add 476 (the actual elevation of my 0,0,0) to the code: str(round(z+476, 1))

Today, I tried to make more generic, so that the code can be used elsewhere. All I did was to add a key to all the height texts - a very self-explanatory key “Actual Elevation of Document’s 0,0,0”.
I gave all of them the 476 value and added the code:
elev = int(rs.GetUserText(id,"Actual Elevation of Document's 0,0,0",False))
obj.TextGeometry.Text =str(round(z+elev, 1))

It worked but it still not satisfying as a generic command. It requires that the text has that key (and I didn’t even troubleshoot what happens if the value is null or the key is absent).

In writing that one line of code :sweat_smile: (it was the first time I opened a python code, and it has been decades since I wrote a bit of RhinoScript), I came across that you can have document Key. So the script would store the elevation on the Document Key, and you did not need to add the same key in all the texts (and to know exactly what key to be added if you start on a new drawing.

And I thought it would be great to have it running as a command line because I am that old that I hardly use buttons/icons or whatever name the kids are calling them these days.

It could go something like this:

FAKECODE Get objects and prompt: "Select texts (Current Reference Elevation = 0)"
FAKECODE When user types E, then ask for document elevation input, then SetDocumentUserText ("Document elevation,userinput)
FAKECODE Then just added to the z-coord of the text

It’s all very clear in my mind :smiley:, but I lack the knowledge to tackle (first) the basics and (second) the error handling.

I might try to do this in RhinoCommon as it would also solve a long standing issue of my own.

I’ve been trying to achieve something similar myself. I also needed to convert the text to imperial. I’ve been able to successfully create a dynamic spot elevation mark using a Visual ARQ annotation component defined in Grasshopper. I don’t think this is a solution for yourself unless you already have the Visual ARQ add-on.

I would be using that solution right now if not for the fact that I wanted to rotate the text both 45 degrees on it’s plane, and then 90 degrees on either the plane’s X or Y axis. Back when I was first using Grasshopper I did something wrong and completely broke the definition. But I think I when I have time to have another go I could get it to work.

I have a couple RhinoCommon solutions that might work (and would also work with python):

One would be to create a block (just text and a point and/or symbol), and then run a RhinoCommon routine to insert that block. When initially inserted the block would display it’s correct elevation. If the block gets moved it won’t update (unless an event is programmed/attached to it), but… you could have one RhinoCommon command for inserting the block, and one for updating all blocks (manually) if one or more moved. The later command could be tacked onto the former so creating a new instance would automatically check/update all existing ones.

The other solution is very similar, but using a specific layer to dictate which points/texts are affected instead of creating blocks. A solution like this would be better if you wanted more flexibility regarding text placement, but would run the risk of texts/points being mixed up.

In RhinoCommon it’s not too hard to run a sweep on the database especially if your drawing isn’t gigantic.

Coming from AutoCAD (and the versatility of it’s available field variables) it’s hard to stomach how much work goes into getting something like this to work. But that’s how it goes when migrating from one program to another. You gain some advantages and lose some others.

@nsgma - this one is updated to check for document user text first as a default elevation. Also allows changing the elevation with pre-selection, and allows typing a number to set the elevaton without going to the option at all.
TextZ.py (2.9 KB)


This works as a charm!!! Exactly as expected.
Thanks a lot, @pascal.

I can group it with a block height symbol, and it works pretty well. But ideally the text should be inside the block… that’s another battle :wink:

Thanks, again, N

This is incomplete but I’m out of time unfortunately. I’m not sure how to set the datum (but that’s probably pretty easy). This also had very limited testing. And… also requires my block (or you’ll have to go in and edit the code to change the block name). The block geometry itself can be changed. If anything changes with the attribute text that will have to be updated in the code as well.

Typing “3DE” will insert the block and create the attribute text as shown above.
Typing “UpdateElevationMarks” will update the text if the block is moved:
I’m not at the level where I know how to automatically update the text (but I can do it with AutoCAD so someday…).

Happy to share but 1) It’d probably be better for a more experienced member to look at the code and 2) I don’t know exactly what I need to share. I’ll have to share the file for sure (for the block), but do I just grab the DLL out of the bin folder?

Regardless, I’ll be back to polish this up at a later date for anyone interested, fix the loose ends and the number’s appearance, etc…

1 Like

Hi @pascal,
Actually, there is something unexpected. I think I know why it is behaving like that, but I am not able to fix it.

When reopening a file where the script has been used, I expected that the variable “elevation” would read the DocumentUser Key that was registered at the end of the script, rather than being set to 0.
The point of registering the elevation in the DocumentUser key is to set it once and be persistent.

Or did I misunderstood how the DocumentUser Key works?
Thanks, N

Hi @keithscadservices
It sounds good. Is the text inside the block? It would be great if you can share.

It is. It’s an attribute inside the block. The code is closely tied to both the block’s name and the attribute’s key’s name. The text has to be an attribute or the code would simply edit every instance. If the block name or attribute key name changes it’s pretty easy to adjust the code… just that the code will need adjustment if that happens is all. This also might only work in the World CPlane Top Coordinates only. I’ve yet to get into working with anything but the default CPlane.

If this is close to working I think the remaining stuff might be easy to solve. A cheeky solution to the datum issue might simply be creating another block with an attribute (or even text would work in this case) and parsing the text into the datum. I’m sure there’s a better way (like a document based attribute) but I’m only just getting into Rhino API. The number format also sucks but I have a few solutions in mind.

This is for testing only. I haven’t shared a plugin yet. To be honest I’m not even sure if I have to share something in addition with the .rph file. The .3dm file is included because as mentioned, you need that block for this to (hopefully) work. Don’t use the code in any file you’re actually using for something important. I caught one issue, that being that it was adding the attribute to every single block instance in the drawing, since fixed… but it still needs more testing.

### - TEMP - PLUGIN TEST.3dm (259.2 KB)
kCs_3D_SpotElevationMark.rhp (41.5 KB)

Per above, the command names are “3DE” to insert the block and “UpdateElevationMarks” to update them if they’ve moved. These can be easily changed in the code.

@nsgma - check my posting with the script - I updated that earlier, I think it does the right thing now.


Hi Pascal,
Thank you again for this and apologies for my silence as other battles took me away from this.
This was and will be very useful.

I was able to add a second option to choose the decimals to round to (attached).

However, there is something unexpected when the objects are preselected: it goes directly to asking the reference elevation and if no input then it exits without changing the text.
I would expect that it should have the same options for the command prompt.
Is there an elegant way of doing that without repeating most of the same lines of code.
TextZ_v04.py (3.5 KB)

Sorry Keith I still had not time to check your method… but it is on my list…