# Python rhinoscriptsyntax custom\_filter question

**URL:** <https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457>\
**Category:** Scripting\
**Created:** [November 29, 2014, 12:58pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457 "2014-11-29T12:58:11Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Helvetosaur](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/helvetosaur/32/635974_2.png) [@Helvetosaur](https://discourse.mcneel.com/u/Helvetosaur)\
**Post date:** [November 29, 2014, 12:58pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/1 "2014-11-29T12:58:11Z")

</div>

I am trying to limit the selection to either a closed planar curve or a planar surface. I have tried all sorts of combinations of different ways to set up the custom filter including more detailed if statements and try/except clauses, but none work correctly, either I can select some things that don’t fit the filter criteria or I can’t select some things that do… Haven’t found the right combination yet. Anyone have any pointers here?

```python
def cp_filt(rhino_object, geometry, component_index):
    a=(rs.IsSurface(geometry) and rs.IsSurfacePlanar(geometry))
    b=(rs.IsCurvePlanar(geometry) and rs.IsCurveClosed(geometry))
    return a | b

def TestFilter():
    msg="Select closed planar curve or planar surface"
    obj=rs.GetObject(msg,4+8,True,custom_filter=cp_filt)
    print obj

```

Thx, --Mitch

---

<div class="post-metadata">

**Author:** ![menno](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/menno/32/770384_2.png) [@menno](https://discourse.mcneel.com/u/menno)\
**Post date:** [November 29, 2014, 2:54pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/2 "2014-11-29T14:54:09Z")

</div>

the filter function has signature `(RhinoObject, GeometryBase, ComponentIndex)`

Looking at the docs I see that `rs.IsSuface` expects an objectId, not a geometry. Same for `IsSurfacePlanar`, `IsCurvePlanar` and `IsCurveCosed`

[http://4.rhino3d.com/5/ironpython/modules/surface\_module.htm](http://4.rhino3d.com/5/ironpython/modules/surface_module.htm)  
[http://4.rhino3d.com/5/ironpython/modules/curve\_module.htm](http://4.rhino3d.com/5/ironpython/modules/curve_module.htm)

So, probably you’d have to write something along the lines of

```auto
def cp_filt(rhino_object, geometry, component_index):
    a=(rs.IsSurface(rhino_object.Id) and rs.IsSurfacePlanar(rhino_object.Id))
    b=(rs.IsCurvePlanar(rhino_object.Id) and rs.IsCurveClosed(rhino_object.Id))
    return a | b

```

Does that help? I may be barking up the wrong tree though…

---

<div class="post-metadata">

**Author:** ![Helvetosaur](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/helvetosaur/32/635974_2.png) [@Helvetosaur](https://discourse.mcneel.com/u/Helvetosaur)\
**Post date:** [November 29, 2014, 4:57pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/3 "2014-11-29T16:57:44Z")

</div>

> [@menno](#):
>
> Does that help?

No unfortunately, that still allows me to select stuff other than the filter specifies, notably non-planar surfaces… But thanks for trying!

Edit - OK, my theory here is that the custom\_filter can’t distinguish basic object types like whether it’s a curve or a surface - but rather just the object type sub characteristics like closed or planar. So when the primary filter feeds it the possibility of two different types of object it gets confused… My evidence:

The following works correctly for closed planar curves:

```python
def cp_filt(rhino_object, geometry, component_index):
    return rs.IsCurvePlanar(geometry) and rs.IsCurveClosed(geometry)

def TestFilter():
    msg="Select planar object"
    obj=rs.GetObject(msg,4,True,custom_filter=cp_filt)
    print obj
TestFilter()

```

Now, add the _possibility_ of selecting surfaces - it then fails (any kind of surface can also be selected):

```python
def cp_filt(rhino_object, geometry, component_index):
    return rs.IsCurvePlanar(geometry) and rs.IsCurveClosed(geometry)

def TestFilter():
    msg="Select planar object"
    obj=rs.GetObject(msg,4+8,True,custom_filter=cp_filt)
    print obj
TestFilter()

```

OK, try filtering for curve objects _inside_ the custom filter:

```python
import rhinoscriptsyntax as rs

def cp_filt(rhino_object, geometry, component_index):
    return rs.IsCurve(geometry) and rs.IsCurvePlanar(geometry) and rs.IsCurveClosed(geometry)

def TestFilter():
    msg="Select planar object"
    obj=rs.GetObject(msg,4+8,True,custom_filter=cp_filt)
    print obj
TestFilter()

```

That also fails, surfaces can still be selected…

–Mitch

---

<div class="post-metadata">

**Author:** ![emilio](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/emilio/32/771014_2.png) [@emilio](https://discourse.mcneel.com/u/emilio)\
**Post date:** [November 29, 2014, 10:19pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/4 "2014-11-29T22:19:21Z")

</div>

Not sure whether you’re looking for a workaround or are trying to understand why that method does not work …  
Anyway, if I understand the problem correctly, nesting the input code inside a loop might work as a workaround:

```python
import rhinoscriptsyntax as rs

id = None
while not id:
    id = rs.GetObject( '?' )
    if not id:
        break
    if rs.IsSurface( id ) and rs.IsSurfacePlanar( id ):
        pass
    elif rs.IsCurve( id ) and rs.IsCurvePlanar( id ):
        pass
    else:
        id = None
print id

```

HTH

---

<div class="post-metadata">

**Author:** ![Jess](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/jess/32/769577_2.png) [@Jess](https://discourse.mcneel.com/u/Jess)\
**Post date:** [November 30, 2014, 4:13pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/5 "2014-11-30T16:13:13Z")

</div>

Hi Mitch, this works for me:

```python
import Rhino
import rhinoscriptsyntax as rs

def cp_filt(rhino_object, geometry, component_index):
    if geometry.IsPlanar():
        if isinstance(geometry, Rhino.Geometry.Curve):
            if not geometry.IsClosed: return False
        return True
    return False

def TestFilter():
    msg="Select planar object"
    obj=rs.GetObject(msg,4+8,True,custom_filter=cp_filt)
    print obj
    
TestFilter()

```

Edit: posted the wrong version, hope this works

---

<div class="post-metadata">

**Author:** ![Helvetosaur](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/helvetosaur/32/635974_2.png) [@Helvetosaur](https://discourse.mcneel.com/u/Helvetosaur)\
**Post date:** [November 30, 2014, 5:42pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/6 "2014-11-30T17:42:08Z")

</div>

Hey Jess,

You nailed it! So, I just have to go deeper into RhinoCommon for this function, this is a lot of help!

Cheers, --Mitch

---

<div class="post-metadata">

**Author:** ![Jess](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/jess/32/769577_2.png) [@Jess](https://discourse.mcneel.com/u/Jess)\
**Post date:** [November 30, 2014, 9:09pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/7 "2014-11-30T21:09:26Z")

</div>

Hi Mitch, well you could also do it with rhinoscriptsyntax, but you’ll have to be more explicit:

```python
import rhinoscriptsyntax as rs

def cp_filt(rhino_object, geometry, component_index):
    if rs.IsCurve(rhino_object.Id):
        if rs.IsCurveClosed(rhino_object.Id):
            if rs.IsCurvePlanar(rhino_object.Id):
                return True
    elif rs.IsSurface(rhino_object.Id):
            if rs.IsSurfacePlanar(rhino_object.Id):
                return True
    return False

def TestFilter():
    msg="Select planar object"
    obj=rs.GetObject(msg,4+8,True,custom_filter=cp_filt)
    print obj
    
TestFilter()

```

In your code you’ve checked surface properties on curves and vice versa. Looks like a custom\_filter is simply being ignored once there is some faulty code inside.

---

<div class="post-metadata">

**Author:** ![Helvetosaur](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/helvetosaur/32/635974_2.png) [@Helvetosaur](https://discourse.mcneel.com/u/Helvetosaur)\
**Post date:** [November 30, 2014, 9:57pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/8 "2014-11-30T21:57:34Z")

</div>

> [@Jess](#):
>
> Looks like a custom\_filter is simply being ignored once there is some faulty code inside.

I had tried all sorts of stuff like that before posting… But somehow never got it right… 😖

---

<div class="post-metadata">

**Author:** ![emilio](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/emilio/32/771014_2.png) [@emilio](https://discourse.mcneel.com/u/emilio)\
**Post date:** [December 2, 2014, 12:57pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/9 "2014-12-02T12:57:15Z")

</div>

Trying to understand a little more, I edited Mitch’s original code applying what Menno and Jess tought us.  
(obviously it works)  
Also, calling a Curve method onto a Surface usually makes the script break, but calling it inside the filter function lets the script run and give meaningless results. Just like Jess said.  
Thanks guys, I’ve learnt something more 😃

```python
import rhinoscriptsyntax as rs

def cp_filt(rhino_object, geometry, component_index):
    a=(rs.IsSurface(rhino_object.Id) and rs.IsSurfacePlanar(rhino_object.Id))
    b=(rs.IsCurve(rhino_object.Id) and rs.IsCurvePlanar(rhino_object.Id) and rs.IsCurveClosed(rhino_object.Id))
    return a | b

def TestFilter():
    msg="Select closed planar curve or planar surface"
    obj=rs.GetObject(msg,4+8,True,custom_filter=cp_filt)
    print obj
    
TestFilter()

```

---

<div class="post-metadata">

**Author:** ![Helvetosaur](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/helvetosaur/32/635974_2.png) [@Helvetosaur](https://discourse.mcneel.com/u/Helvetosaur)\
**Post date:** [May 28, 2015, 3:15pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/10 "2015-05-28T15:15:14Z")

</div>

@stevebaer I think I found a bug in one of these things:

This works to isolate polycurves:

```python
import rhinoscriptsyntax as rs
import Rhino

#polycurves, but no polylines
def pcrv_filt(rhino_object, geometry, component_index):
    return rs.IsPolyCurve(geometry)

def TestFilter():
    msg="Select polycurves to test"
    crvIDs=rs.GetObjects(msg,4,preselect=True,custom_filter=pcrv_filt)
    if not crvIDs: return
TestFilter()

```

and this doesn’t:

```python
import rhinoscriptsyntax as rs
import Rhino

#polycurves, but no polylines
def pcrv_filt(rhino_object, geometry, component_index):
    return geometry.IsPolyCurve()

def TestFilter():
    msg="Select polycurves to test"
    crvIDs=rs.GetObjects(msg,4,preselect=True,custom_filter=pcrv_filt)
    if not crvIDs: return
TestFilter()

```

For selecting polylines, for example, if you change _PolyCurve_ to _Polyline_, they both work…

Note that `return isinstance(geometry, Rhino.Geometry.PolyCurve)` also works…

–Mitch

---

<div class="post-metadata">

**Author:** ![stevebaer](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/stevebaer/32/473567_2.png) [@stevebaer](https://discourse.mcneel.com/u/stevebaer)\
**Post date:** [May 28, 2015, 3:31pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/11 "2015-05-28T15:31:17Z")

</div>

@alain can you look into this?

---

<div class="post-metadata">

**Author:** ![Alain](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/alain/32/512812_2.png) [@Alain](https://discourse.mcneel.com/u/Alain)\
**Post date:** [May 28, 2015, 5:12pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/12 "2015-05-28T17:12:15Z")

</div>

> [@Helvetosaur](#):
>
> return geometry.IsPolyCurve()

Hey Mitch,  
I don’t see such a method in RhinoCommon.

---

<div class="post-metadata">

**Author:** ![Helvetosaur](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/helvetosaur/32/635974_2.png) [@Helvetosaur](https://discourse.mcneel.com/u/Helvetosaur)\
**Post date:** [May 28, 2015, 6:58pm UTC](https://discourse.mcneel.com/t/python-rhinoscriptsyntax-custom-filter-question/14457/13 "2015-05-28T18:58:56Z")

</div>

> [@Alain](#):
>
> I don’t see such a method in RhinoCommon.

Hey Alain,  
You’re right, my bad, I didn’t look, I just assumed that it was there like IsPolyline(). Sorry for the noise… 🙉
