Where is rs.filter.surface coming from

Hi,

I have seen somewhere on the forum the rs.GetObject with rs.filter.surface.
Where rs.filter.surface come from?

Thanks,
Andras

Used inside the various ā€œGetā€¦ā€ functions for example, it limits the selection to surface objects…

Thank you,

I am basically looking for the documentation of the rs.filter to find out the options and type of filterable objects that is available for this method.

Looks like it’s an undocumented feature, but digging through the rhinoscript.selection source code reveals that filter is an enum-like class with a corresponding internal function __FilterHelper() that translates it into RhinoCommon objects.

These are the types of geometry that you can filter:

  • allobjects ( the default option - no effect )
  • point
  • pointcloud
  • curve
  • surface
  • polysurface
  • mesh
  • light
  • annotation
  • instance
  • textdot
  • grip
  • detail
  • hatch
  • morph
  • cage
  • phantom
  • clippingplane
  • extrusion

and you use it by passing it into the filter argument of the functions:

  • rs.GetObject
  • rs.GetObjectEx
  • rs.GetObjects
  • rs.GetObjectsEx

optionally combining several filters with the | bitwise-OR operator, eg.

rs.GetObjectEx(message="Choose wisely!", filter=(rs.filter.mesh | rs.filter.polysurface))

The enumeration you find here in selection.py:

image

as well as here in rs.ObjectsByType():

can also be used as shorthand to pass as a geometry filter to the ā€œGetā€ methods. You can add numerical values as needed, i.e. passing 8+16 does the same thing as passing rs.filter.Surface | rs.filter.polysurface… It’s less verbose, but it does save a lot of line length…

1 Like

I would never recommend sacrificing that much readability for a bit of line length savings though, especially in Python - imagine coming across this code without the benefit of comments or keyword arguments:

rs.GetObjects("", 1+4, True) 

versus the self-documenting

rs.GetObjects("", rs.filter.point |
                  rs.filter.curve, preselect=True) 
1 Like

Well, I do it all the time, each to his own. I expect most people coding to know the object type enumerations - as they are so basic and have existed since Rhinoscript has - especially 1, 2, 4, 8, 16 and 32. I was however not so happy when they added extrusions (1073741824) in V5, as that’s too hard to remember… :stuck_out_tongue_closed_eyes:

As an aside in vb Rhinoscript, the concept of filter via object type name does not exist as far as I know, all you can supply is the integer representing the object type… Rhino.ObjectType() also just returns an integer - as does rs.ObjectType() in python rhinoscriptsyntax.

No intention of starting a coding-style debate here, but the official Zen of Python says otherwise :smiley:

[…]
Explicit is better than implicit.
[…]
Readability counts.

</appeal_to_authority>

Rhino.DocObjects.ObjectType is a .NET Enum type, the whole purpose which is to enforce this sort of readability and type safety for symbolic arguments- Python doesn’t have a builtin enum type, which I guess is why rhinoscript defaults to using plain integers and then converting them to ObjectType behind the scenes.

( I’ve never used VB myself so I’m not sure if it does implicit enum-to-int casting, but certainly this doesn’t happen in C# )

PS. they’re all powers of two so you could write 1 << 30 or 0x40000000 or even 0b100000000000000000000000000000 (30 zeroes) instead of the ugly decimal representation :slight_smile:

Whoa, just spotted a typo there: rs.filter.morph should be 131072 (2^17) , not 13072 !

Bug verified in GH:
image

@piac https://github.com/mcneel/rhinoscriptsyntax/blob/rhino-6.x/Scripts/rhinoscript/selection.py#L24

Me neither, I don’t consider myself a coder, just a ā€˜toolmaker’ who makes tools for myself and others. For me line length is important for readability so I much prefer this:

import rhinoscriptsyntax as rs

#filter solid breps + closed meshes
def clsd_vol_filt(rhino_object, geometry, component_index):
    if rs.IsMesh(geometry): return rs.IsMeshClosed(geometry)
    if rs.IsBrep(geometry): return rs.IsObjectSolid(geometry)

msg='Select closed surfaces, polysurfaces or meshes to process'
objIDs=rs.GetObjects(msg,8+16+32,preselect=True,custom_filter=clsd_vol_filt)
print '{} objects selected'.format(len(objIDs) if objIDs else 'No')

to this:

import rhinoscriptsyntax as rs

#solid breps + closed meshes
def clsd_vol_filt(rhino_object, geometry, component_index):
    if rs.IsMesh(geometry): return rs.IsMeshClosed(geometry)
    if rs.IsBrep(geometry): return rs.IsObjectSolid(geometry)

objIDs=rs.GetObjects('Select closed surfaces, polysurfaces or meshes to process' 
,rs.filter.surface | rs.filter.polysurface | rs.filter.mesh, 
preselect=True,custom_filter=clsd_vol_filt)

print '{} objects selected'.format(len(objIDs) if objIDs else 'No')

But again, whatever works…

Thanks @qythium, I just reported RH-44902.