Need a script that can do what SelBoundary is doing, in Py

Ok, so I have some closed curves with texts in them, each curve with only 1 text. I need to rename the curves using the text and with rs.Command("_SelBoundary selid {} _Enter".format(str(obi))) line I manage to get the text of the obi curve, the problem is on 10-15 curves the script works with no problem, but I have around ~300 curves and sometimes it gets 2 different texts. This is the Script I am using:

obj = rs.AllObjects(select=False)

i = 1

#Creates the Groups
for obi in obj:
    
    if rs.ObjectType(obi) == 4:
        
        rs.UnselectAllObjects()
        
        crv.append(obi)
        rs.AddGroup(i)
        rs.AddObjectToGroup(obi, i)
        rs.Command("_SelBoundary selid {} _Enter".format(str(obi)))
        a = rs.SelectedObjects()
        rs.UnselectAllObjects()
        rs.AddObjectToGroup(a, i)
        i += 1

So, do you know any replacement for “SelBoundary” command?

1 Like

Hello,

Can you share a file which gives the behaviour you are describing? This may help people to work out what is going on…

Could a workaround be to use rs.CurveAreaCentroid to get the centre of each curve and then select the closest text object to that point using PointClosestObject?

Have you tried changing the SelectionMode?

rs.Command("_SelBoundary _SelectionMode=_Window selid {} _Enter".format(str(obi)))

Or

rs.Command("_SelBoundary _SelectionMode=_Crossing selid {} _Enter".format(str(obi)))

and maybe add a check that it is a textbox before adding to group:

if rs.IsText(a):
    rs.AddObjectToGroup(a, i)

Last suggestion: if you don’t need to keep track of the group names. You could just let AddGroup autogenerate a name rather than passing ‘i’ in.

AddGroup(group_name=None) Adds a new empty group to the document

Parameters:
group_name (str, optional): name of the new group.

If omitted, rhino automatically generates the group name

I actually asked a related question without realizing you had posted this question yesterday. Here is my post in case someone replies to mine. Select Contents of Closed Curve

1 Like

RenamingParts.3dm (3.1 MB)
This is the file I’m testing the script.
I have tried all the forms for _SelBoundary and the problem is not that what it finds is or is not a text, the problem is that it selects texts that are not inside the boundary.

Graham, I have tried your idea with rs.CurveAreaCentroid and rs.PointClosestObject but I can’t seem to get around how rs.PointClosestObject actually works

I used it like this:
pt = rs.CurveAreaCentroid(crv)
text = rs.PointClosestObject(pt[0], Text)
rs.ObjectName(crv, rs.TextObjectText(text[0]))
And it gives the error 'NoneType' object is not subscriptable where crv is an array with all curves GUID’s and Text with all text GUID’s

Hi,

tried it today to select text in boundary (closed curves).
I used the Curve.BoundingBox.Contains method.
Its made in grasshopper python but it should work in rhino python also.
Hope it helps to give a idea how to achieve your result.

import Rhino as rh

CuType = rh.DocObjects.ObjectType.Curve
TeType = rh.DocObjects.ObjectType.Annotation

BB = []
for i in rh.RhinoDoc.ActiveDoc.Objects.GetObjectList(CuType):
    if i.Geometry.IsClosed:
        BB.append(i.Geometry.GetBoundingBox(False))

BoundaryText = []
for i in rh.RhinoDoc.ActiveDoc.Objects.GetObjectList(TeType):
    CenterPointText = i.Geometry.GetBoundingBox(False).Center
    for b in BB:
        if b.Contains(CenterPointText):
            BoundaryText.append(i)

if select:
    for i in BoundaryText:
        i.Select(True)
elif deselect:
    for i in BoundaryText:
        i.Select(False)


select_Boundary_Text.3dm (3.2 MB) select_Boundary_Text.gh (3.2 KB)

I don’t know if you ever figured this out, but @Helvetosaur gave some very helpful advice on my post.

If you use TextObjectPoint() and PointInPlanarClosedCurve() together, you can get some very fast results without SelBoundary. Just pass your closed curve and the text point into PointInPlanarClosedCurve(), as well as the closed curve’s plane which can be acquired from CurvePlane().

If you need any clarification let me know.