Object selection according to a user-defined sequence?

Hi. I’m not all that conversant with Python, so you’ll have to forgive me if this has a really obvious answer.
What I’m trying to achieve is this: I want people to be able to drop a particular type of drawing into rhino, and execute a script that will prepare the drawing for lasercutting. I’ve got 95% of the scripting worked out, although there is one thing that’s eluding me at the moment- I need to be able to automatically select and rename objects in a linear sequence, according to the direction of the drawing.

For the sake of example, say I have a set of 25 concentric arcs, with the open end facing right - I want to be able to name the arcs ‘arc01’ through to ‘arc25’ from left to right, where the largest (leftmost) arc is 01. However, not every drawing is going to be laid out in that direction, so I need to be able to define which arc is going to be arc01, and let the computer do the rest in the correct order.

I’ve had mixed success using a simple for loop to select and rename objects, although it’ll go from left to right on my home computer, and right to left on my work computer - it’s the same starting document, so I have no idea what sorcery is at work here.

If I were to include a ‘select starting curve’ and ‘select ending curve’ step into the program, would there be any way of getting rhino/python to work to the implicit order sensibly, or am I letting myself in for a world of pain?

Thanks

If you want this to work reliably, you are going to want to sort the objects “geographically”, that is to say not rely on the order in the file, but on their physical placement. To do that you will need to get some point on each object - say the center of its bounding box - and then sort the points in the order you want, bringing the objects themselves along in a parallel sort.

rhinoscriptsyntax has a few tools to help - notably rs.SortPoints() - but to develop a parallel sorting routine you will probably need to use a dictionary. Let me see if I can work up a quick example.

–Mitch

1 Like

I had wondered about doing something like that - getting the user to draw a line with the intersection points tagged in ascending ‘x’ order, and using that. However, since the curves are pretty complicated compound curves, am I likely to run into any problems caused by there being a bajillion segments per curve?

:edit:
So, CurveCurveIntersection looks like a primary start for being able to determine point placement, although it’s only really set up to handle two curves - I’m guessing that some cunningly nested for loops will allow me to traverse the length of the user-defined intersection line, and generate the points in question.

I’m going to have a bit of a scratch around and see what I can knock together, although I have no doubt that you’ll be able to blow my coding skills out of the water in short order. Thanks for the information thus far - it’s definitely gotten me out of the conceptual rut that I was stuck in.

I don’t think so… As long as Rhino can find one unique intersection point for each curve.

Sorry, got interrupted by students here… Below is a quick sample of code, with attached file having 25 arcs as you described, but in random order in the file…

25Arcs.3dm (265.8 KB)

import rhinoscriptsyntax as rs

#gets object bounding box center
def BBCtr(objID):
    bb=rs.BoundingBox(objID)
    return (bb[0]+bb[6])/2
    
def TestObjectNameSort():
    objIDs=rs.GetObjects("Select objects to sort",preselect=True)
    if not objIDs: return
    
    #create a list of bounding box centers
    bb_ctrs=[BBCtr(objID)for objID in objIDs]
    
    #zip object's bb center together with the object id
    obj_ctr_dict=dict(zip(bb_ctrs,objIDs))
    
    sort_order=0 #sorts X, Y, Z
    #sort your points (True=ascending)
    sorted_ctrs=rs.SortPoints(bb_ctrs,True,sort_order)
    
    #now name the objects in order using the dictionary relationship w/sorted pts.
    for i,pt in enumerate(sorted_ctrs):
        text="Object number {}".format(i+1)
        rs.ObjectName(obj_ctr_dict[pt],text)
TestObjectNameSort()

Edit - actually due to a typo, I just had the order wrong in the optional argument for sorting ascending/descending, it actually works, no bug, script corrected above, sorry…

3 Likes

That’s absolutely spot on. Thank you - not only for the script, but also for the concise commenting.

thanks a lot , this saved me lots of time. Made some modification via chatty !Works like a charm.