Rs.SelectObject acts differently under OSX and Windows

I am looping through a set of objects, and I want all instances of non-closed curves to be selected when finished. So when a non-closed curve is encountered, the curve gets selected and the loop restarted to find the next one. The odd thing is that the script works as intended on my Mac, but I am sharing this with a friend who runs the same script on a Windows PC, and he is finding that only the last encountered non-closed curve remains selected, and not the earlier found ones. This is identical to picking them by hand, and it is what I expected to happen in the first place, but what surprises me is the difference between the operating systems.

My script:

#Create Layer Name Text Object for Surfaces and closed curves, Max Zuijdendorp, April 2015

import rhinoscriptsyntax as rs

# Check if a layer "Layer Names" exists, if not, add it.
if not rs.IsLayer("Layer Names"):
    rs.AddLayer("Layer Names", (0,0,0))

# Make "Layer Names" the current layer
rs.CurrentLayer("Layer Names")

def labelling():
	if rs.IsCurve(obj):
		if (rs.IsCurveClosed(obj)==False):
			rs.SelectObject(obj)
			rs.MessageBox("Non-closed curve encountered")
			return
		origin = rs.CurveAreaCentroid(obj)
	elif rs.IsSurface(obj):
		origin = rs.SurfaceAreaCentroid(obj)
		
	point = rs.AddPoint(origin[0])

	laag=rs.ObjectLayer(obj)
	namepart=laag.split("::")
	laag=namepart[-1]

	group=rs.AddGroup()
	rs.AddObjectToGroup(obj,group)
	
	#create your text object and group with object
	objecttext=rs.AddText(laag,point,height=8,font="Arial",font_style=0,justification=2)

	rs.DeleteObject(point)

	rs.AddObjectToGroup(objecttext,group)

more=1
while(more==1):
	# Pick a set of surfaces or closed curves to be identified with the layer name
	objects = rs.GetObjects("Select Surfaces or closed curves to label", filter=12, preselect=False, select=False)

	if objects:
		for obj in objects:
			labelling()

	more=rs.MessageBox("Do you want to place more labels?",buttons=1)

Max.

Dunno, the way you have it written, here at least (Windows) it selects the non-closed curves sequentially - after clicking OK at each message box that says “Non-closed curve encountered”. They all remain selected at the end.

–Mitch

Hi,

I tried your script with the latest wip of Rhino on the Mac and with Rhino 5 SR 11 and got the same results. Do you have the latest versions?

This is where you can get a little more sophisticated with your python scripting - you can actually prevent the user from selecting non-closed curves in the first place by using a custom object filter in rs.GetObjects().
Try the following scriptlet:

import rhinoscriptsyntax as rs

def cCrv_filt(rhino_object, geometry, component_index):
    return rs.IsCurveClosed(geometry)
    
closed_crvs=rs.GetObjects("Select curves",4,select=True,custom_filter=cCrv_filt)

You can also combine different types of objects, it takes a bit more juggling:

import rhinoscriptsyntax as rs

def cCrv_Srf_filt(rhino_object, geometry, component_index):
    if rs.IsCurve(geometry):
        if rs.IsCurveClosed(geometry): return True
    elif rs.IsSurface(geometry): return True
    else: return False
    
stuf=rs.GetObjects("Select objects",4+8,select=True,custom_filter=cCrv_Srf_filt)

–Mitch

Thanks Mitch, but I am afraid I have lost you there, can you explain a bit further?

Besides that, one of the objectives of my script was to alert the user that some of the curves he has selected are supposed to be closed, but are not. So I do not want those to be filtered out before further processing.

@Alain I am using the latest wip, but I will have to check with my friend on his Rhino 5 version.

Max.

OK, no problem… The custom_filter argument in GetObject(s) is a “helper” function. It allows you to refine the choice you have made with the main filter argument - which only distinguishes main classes of objects like curves, surfaces, polysurfaces, meshes, etc.

So, with the custom filter argument, you can operate within those classes of objects and further qualify them to open/closed, planar, or actually pretty much any criteria or combination thereof that applies to that class of object. For example, you could make a custom filter that would only let the user select red planar closed curves that are between 5 and 10 mm long and have a certain linetype applied… OK, that’s extreme, but it avoids having to throw out non-applicable items later, plus the user sees what items actually are selectable.

The function is relatively simple, if the filter returns True, the item can be selected, if it returns False or None, the item can’t be selected. It works pretty much like a normal function definition, you can use if statements and rhinoscriptsyntax or RhinoCommon methods to check if objects meet your criteria.There are a couple of tricky bits if you want to filter several types of object classes together like curves and surfaces.

Hope that explains a bit better… It’s a bit advanced, but just throwing it out there. --Mitch

Sorry guys, it was just a plain misunderstanding between me and the other user. His comment is that all gets unselected as soon as you choose to process more objects, and that makes sense since the preselect argument in GetObjects() is False, so everything gets unselected.

Mitch, thanks for the explanation, but I am still unclear as to what the arguments of the custom filter (rhino_object, geometry, component_index) represent. Inexperience I am afraid.

Max.

You don’t actually need to do anything to/with those in this case, it’s always the same. Just copy/paste… --Mitch