Rhino Script to Generate Points from Text

Hi there, we are regularly working with topographical surveys with spot heights taken at multiple locations on the site.

We are looking for a Rhino 5.0 script which allows you to select the texts and then creates points a certain distance away above the text based on what the text reads. For example, if the text shows 43.21, the script should create a point exactly 43.21 units away on the Z axis.

Your help would be greatly appreciated.

Thanks in advance!

Here is a fairly deep dive on reading point cloud files with python scripting:

The code samples could probably be adapted to your use case easily.

Spot Heights.3dm (875.0 KB)
Thank you for the quick reply! I had a look at the topic, but I don’t think this is what we had in mind.

Sorry, I didn’t make that clear. The text is already imported from .dwg in Rhino as separate text points in the correct location.
Just need to select all of them and create a point for their height based on what they read.
I have attached the .3dm, if that helps at all.

Thanks!

You can try this script from my library and see if it works for you…

CreatePointsAtTextHeight.py (1.1 KB)

Your file is in mm, but I believe the heights should be in m (according to the content)… So maybe first change the units in the file to meters and accept the scale prompt (will not affect the texts themselves, just the xy location scale)

Also, the script above will not parse anything that is not a pure number, so the entries like

Ridge:63.91

will not get a height point. I would need to do some fancy checking (maybe with regex, ugh) to extract any numbers contained with letters in alphanumeric text strings.

Hey, this is exactly what we needed!

Thank you very much, Helvetosaur. Saved the day (and a lot of time)!

If you have a problem and you decide to solve it with regex then you have 2 problems :slight_smile:

https://regex101.com/ can help with this…This should do the trick:

r"[+-]?\d+(?:\.\d+)?"
2 Likes
r"[+-]?\d+(?:\.\d+)?"

When I see that, I think

"%&^#()&(@%$!!!!!"

:stuck_out_tongue_winking_eye:

2 Likes

Looks like @Helvetosaur beat me to it but here is another solution with simple number extraction and scale option:

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']

def parse_text(text):
    # probably not performant but simple
    new_string = ''
    for char in text:
        if char in numbers:
            new_string += char
    return float(new_string)


def parse_text_objs():
    # unit stuff
    units = {'mm': Rhino.UnitSystem.Millimeters,
             'm': Rhino.UnitSystem.Meters,
             'inch': Rhino.UnitSystem.Inches,
             'feet': Rhino.UnitSystem.Feet,
             }
    doc_units = sc.doc.ModelUnitSystem
    unit = rs.GetString('select dimension units', 'm', units.keys())
    dim_units = units.get(unit, None)
    if dim_units is None:
        print 'unsupported units, using mm'
        dim_units = units['mm']
    factor = Rhino.RhinoMath.UnitScale(dim_units, doc_units)
    # object selection
    guids = rs.GetObjects('select text objects')
    # turn off redraw for faster loop
    sc.doc.Views.RedrawEnabled = False
    for guid in guids:
        geo = rs.coercegeometry(guid)
        if type(geo) == Rhino.Geometry.TextEntity:
            # use the text entity plane origin as base point
            plane = geo.Plane
            # parse out the numbers in the text
            height = parse_text(geo.Text)
            # make a new point at plane origin with new z scaled
            point = Rhino.Geometry.Point3d(plane.OriginX, plane.OriginY, height*factor)
            # add point to the doc
            sc.doc.Objects.AddPoint(point)
        
    sc.doc.Views.RedrawEnabled = True
    
    
parse_text_objs()

Output for mm and m scale (2 runs) on the example file:

1 Like