How to get the position of text object?

what I want to do

I’d like to get the xyz position of the (anchor point of) the text objects on a layer.

what I’ve explored

As shown in this notebook :

  1. I used rhino3dm.File3dm.Objects to get the ObjectTable of the .3dm file
  2. iterate the object table, and check if an object is on the layer storing the text by examining its File3dmObject.Attributes.LayerIndex

the obstacle

I couldn’t find a way to get the xyz coordinates of a text object.

For text object, File3dmObject.Geometry returns an AnnotationBase object, which only contains the content of the text, via File3dmObject.Geometry.PlainText attribute, or AnnotationBase.PlainText.

my question

Which type of objects/attributes should I access to get the xyz coordinates of text object on a given layer?

Thanks.

code snippet

layer_idx_of_num = 3
cnt_text = 0
max_num_obj = 3
total_num_text = 0

for idx, obj in enumerate(iter(object_table)):
    if (obj.Attributes.LayerIndex == layer_idx_of_num) and (cnt_text < max_num_obj):
        print('object ', idx, ' Object                  : ', obj)
        print('       ', idx, ' Geometry                : ', obj.Geometry)
        print('       ', idx, ' Attributes              : ', obj.Attributes)
        print('       ', idx, ' Attributes.Id           : ', obj.Attributes.Id)
        print('       ', idx, ' Attributes.Name         : ', obj.Attributes.Name)
        print('       ', idx, ' Attributes.LayerIndex   : ', obj.Attributes.LayerIndex)
        print('       ', idx, ' Attributes.ObjectColor  : ', obj.Attributes.ObjectColor)
        print('       ', idx, ' Attributes.Visible      : ', obj.Attributes.Visible)
        print()

        # if geom is AnnotationBase, print its PlainText
        if isinstance(obj.Geometry, rhino3dm.AnnotationBase):
            print('            Geometry.PlainText     : ', obj.Geometry.PlainText)
            print()

        cnt_text += 1

for idx, obj in enumerate(iter(object_table)):
    if (obj.Attributes.LayerIndex == layer_idx_of_num):
        total_num_text += 1

print('total num of text: ', total_num_text)

output

object  2472  Object                  :  <rhino3dm._rhino3dm.File3dmObject object at 0x000001792661F6F0>
        2472  Geometry                :  <rhino3dm._rhino3dm.AnnotationBase object at 0x000001791FAD9370>
        2472  Attributes              :  <rhino3dm._rhino3dm.ObjectAttributes object at 0x000001791FAD9370>
        2472  Attributes.Id           :  331127a8-6c28-4a2e-b56b-6d8c0879f793
        2472  Attributes.Name         :  
        2472  Attributes.LayerIndex   :  3
        2472  Attributes.ObjectColor  :  (0, 0, 0, 255)
        2472  Attributes.Visible      :  True

            Geometry.PlainText     :  5-5-9

object  2473  Object                  :  <rhino3dm._rhino3dm.File3dmObject object at 0x000001792661C2B0>
        2473  Geometry                :  <rhino3dm._rhino3dm.AnnotationBase object at 0x000001791FAD9370>
        2473  Attributes              :  <rhino3dm._rhino3dm.ObjectAttributes object at 0x000001791FAD9370>
        2473  Attributes.Id           :  889cae8f-6c0e-4199-b2e2-1852feccefb4
        2473  Attributes.Name         :  
        2473  Attributes.LayerIndex   :  3
        2473  Attributes.ObjectColor  :  (0, 0, 0, 255)
        2473  Attributes.Visible      :  True

            Geometry.PlainText     :  2-2-5

object  2474  Object                  :  <rhino3dm._rhino3dm.File3dmObject object at 0x0000017975CA6DF0>
        2474  Geometry                :  <rhino3dm._rhino3dm.AnnotationBase object at 0x000001792661C2B0>
        2474  Attributes              :  <rhino3dm._rhino3dm.ObjectAttributes object at 0x000001792661C2B0>
        2474  Attributes.Id           :  937bb06e-49ff-4687-8b42-97ea498f93a0
        2474  Attributes.Name         :  
        2474  Attributes.LayerIndex   :  3
        2474  Attributes.ObjectColor  :  (0, 0, 0, 255)
        2474  Attributes.Visible      :  True

            Geometry.PlainText     :  8-8-6

total num of text:  72

A TextObject has a TextGeometry property that returns the TextEntity. The TextEntity has a Plane property which returns the plane the TextEntity sits on. The Plane has an Origin property which returns the Point that is the co-ordinate of the text (in world units).

The plane gives you 3D orientation of the text as well as its origin. (And it has OriginX, OriginY and OriginZ properties if you want individual values.)

HTH
Jeremy

1 Like

The rhino3dm Python library doesn’t wrap all the necessary things yet for that to be able to ask for.

I am currently working on wrapping the API for leaders, dimensions and text entities.

1 Like

Thanks. Looking forward to your tools to access text objects in .3dm file.

There is a TextDot class in rhino3dm.py, but it seems that it can only be used to add new TextDot to a 3dm file, and not for accessing existing TextDot objects in a 3dm file…sadly…

For the time being, I’ll have to export text objects, including their contents and anchor points, from rhino as a CSV file so that I can access them from rhino3dm.py

TextDot can be read from .3dm files. A text dot is this in Rhino

Addet with the _Dot command.

Reading it in with rhino3dm:

image

It is text entities added with the command _Text that don’t have read access to information like location just yet. This currently missing API is what I am wrapping among things.

1 Like

Thank you very much, @nathanletwory

Yes, following your suggestion, I managed to read TextDot objects in a 3dm file using rhino3dm.py, and I can access their positions and text contents via the rhino3dm.TextDot class.

exmaple TextDot objects in the test 3dm file:

code snippet:

rhino_f_path_text_dot = './data/test_text_dot.3dm'
file3dm_text_dot = rhino3dm.File3dm.Read(rhino_f_path_text_dot)
print(file3dm_text_dot)

text_dot_obj_table = file3dm_text_dot.Objects
print('textDot objects: ', text_dot_obj_table)

for idx, text_dot_obj in enumerate(iter(text_dot_obj_table)):
    print('textDot obj ', idx, ' : ', text_dot_obj)

    text_dot_geom = text_dot_obj.Geometry

    if isinstance(text_dot_geom, rhino3dm.TextDot):
        print('    textDot obj: ', text_dot_geom)
        print('    textDot point: ', text_dot_geom.Point)
        print('    textDot Text: ', text_dot_geom.Text)

    print()

output

textDot objects:  <rhino3dm._rhino3dm.File3dmObjectTable object at 0x0000022099DB26B0>
textDot obj  0  :  <rhino3dm._rhino3dm.File3dmObject object at 0x0000022098023570>
    textDot obj:  <rhino3dm._rhino3dm.TextDot object at 0x0000022099CDF370>
    textDot point:  14.298569362095407,251.0734261769187,0.0
    textDot Text:  8-8-6

textDot obj  1  :  <rhino3dm._rhino3dm.File3dmObject object at 0x000002209A2C87B0>
    textDot obj:  <rhino3dm._rhino3dm.TextDot object at 0x000002209A2CA930>
    textDot point:  7.675239846498812,248.7881056446808,0.0
    textDot Text:  8-8-5

Code snippet updated

# read 3dm file as File3dm object
rhino_f_path = "./data/nongke.3dm"
file3dm_obj = rhino3dm.File3dm.Read(rhino_f_path)

# get the object table
object_table = file3dm_obj.Objects

max_num_obj = 3
cnt_textDot = 0
total_num_textDot = 0

# iterate the object table, and check if object is an instance of rhino3dm.TextDot class
for idx, obj in enumerate(iter(object_table)):
    obj_geom = obj.Geometry

    # get TextDot object's geometry and attributes
    if (isinstance(obj_geom, rhino3dm.TextDot)) and (cnt_textDot < max_num_obj):
        print('textDot object ', idx, ' : ', obj_geom)
        print('        position            : ', obj_geom.Point)
        print('        text                : ', obj_geom.Text)
        print('        attribs             : ', obj.Attributes)
        print('        attribs.Id          : ', obj.Attributes.Id)
        print('        attribs.Name        : ', obj.Attributes.Name)
        print('        attribs.LayerIndex  : ', obj.Attributes.LayerIndex)
        print('        attribs.ObjectColor : ', obj.Attributes.ObjectColor)
        print('        attribs.Visible     : ', obj.Attributes.Visible)
        print()

        cnt_textDot += 1

for idx, obj in enumerate(iter(object_table)):
    if isinstance(obj.Geometry, rhino3dm.TextDot):
        total_num_textDot += 1

print('total num of textDot: ', total_num_textDot)

Output

textDot object  4872  :  <rhino3dm._rhino3dm.TextDot object at 0x000001CDAF307C30>
        position            :  27.064173777436537,200.67848337106952,0.0
        text                :  6-6-1
        attribs             :  <rhino3dm._rhino3dm.ObjectAttributes object at 0x000001CDD9085CF0>
        attribs.Id          :  ace09291-2363-4c79-a99d-2ae7be61531d
        attribs.Name        :  
        attribs.LayerIndex  :  3
        attribs.ObjectColor :  (0, 0, 0, 255)
        attribs.Visible     :  True

textDot object  4873  :  <rhino3dm._rhino3dm.TextDot object at 0x000001CDD9093CF0>
        position            :  35.21171531476992,205.36180830113673,0.0
        text                :  1-1-1
        attribs             :  <rhino3dm._rhino3dm.ObjectAttributes object at 0x000001CDD9085CF0>
        attribs.Id          :  b7bc5562-82b9-4119-b8ef-aa9c68ce3dee
        attribs.Name        :  
        attribs.LayerIndex  :  3
        attribs.ObjectColor :  (0, 0, 0, 255)
        attribs.Visible     :  True

textDot object  4874  :  <rhino3dm._rhino3dm.TextDot object at 0x000001CDD9085CF0>
        position            :  42.1912202855743,199.72217247117237,0.0
        text                :  1-1-2
        attribs             :  <rhino3dm._rhino3dm.ObjectAttributes object at 0x000001CDD8B4DB70>
        attribs.Id          :  65b8075f-ceac-48f6-9b96-6d021fe2ad2a
        attribs.Name        :  
        attribs.LayerIndex  :  3
        attribs.ObjectColor :  (0, 0, 0, 255)
        attribs.Visible     :  True

total num of textDot:  72