developer:sdksamples:customgeometryfilter


How To: Create a Custom CRhinoGetObject Class

C++, .NET

Summary: Demonstrates how to derive a class from CRhinoGetObject to handle special case object picking.

The CRhinoGetObject class that is used for interactively picking one or more objects is a large, full-featured class (see rhinoSdkGetObject.h for details). But, on occasion, the class does not offer enough options. For example, CRhinoGetObject is capable of picking curve objects. But, it is not capable of picking polyline curve objects that are closed. When the required object filtering exceeds the capabilities of the base class, it's time to derive your own.

CRhinoGetObject has a virtual function named CustomGeometryFilter() that is called after all obvious geometry filter checks have been performed. Thus, if you derive a new class from CRhinoGetObject and override this virtual member, you can filter for most any geometric object or property.

The following example code demonstrates deriving from CRhinoGetObject. In this example, we want to allow the user to only select closed polylines.

C++

class CRhGetClosedPolylineObject : public CRhinoGetObject
{
public:
  bool CustomGeometryFilter( 
        const CRhinoObject* obj, 
        const ON_Geometry* geom, 
        RHINO_COMPONENT_INDEX idx 
        ) const;
};
 
bool CRhGetClosedPolylineObject::CustomGeometryFilter( 
        const CRhinoObject* obj, 
        const ON_Geometry* geom, 
        RHINO_COMPONENT_INDEX idx 
        ) const
{
  if( geom )
  {
    // is it a polyline?
    if( const ON_PolylineCurve* p = ON_PolylineCurve::Cast(geom) )
    {
      if( p->IsClosed() && p->IsPolyline() > 3 )
        return true;
    }
    // is is a polycurve that looks like a polyline?
    if( const ON_PolyCurve* p = ON_PolyCurve::Cast(geom) )
    {
      if( p->IsClosed() && p->IsPolyline() > 3 )
        return true;
    }
    // is it a [[rhino:nurbs|NURBs]] curve that looks like a polyline?
    if( const ON_Curve* p = ON_Curve::Cast(geom) )
    {
      ON_NurbsCurve n;
      if( p->GetNurbForm(n) )
      {
        if( n.IsClosed() && n.IsPolyline() > 3 )
          return true;
      }
    }
  }
  return false;
}

We can use the above class as follows:

CRhGetClosedPolylineObject go;
go.SetCommandPrompt( L"Select closed polyline" );
go.SetGeometryFilter( CRhinoGetObject::curve_object );
go.GetObjects( 1, 1 );
if( go.CommandResult() == CRhinoCommand::success )
{
  // TODO...
}

VB.NET

Private Class CRhGetClosedPolyline
  Inherits MRhinoGetObject
 
  Public Overrides Function CustomGeometryFilter(ByVal rh_object As IRhinoObject,_
    ByVal geom As IOnGeometry, ByVal component_index As OnCOMPONENT_INDEX) As Boolean
 
    If (geom IsNot Nothing) Then
      ' is it a polyline?
      Dim polyline As IOnPolylineCurve = OnPolylineCurve.ConstCast(geom)
      If (polyline IsNot Nothing) Then
        If (polyline.IsClosed() And polyline.ispolyline() > 3) Then Return True
      End If
 
      ' is it a polycurve that looks like a polyline?
      Dim polycrv As IOnPolyCurve = OnPolyCurve.ConstCast(geom)
      If (polycrv IsNot Nothing) Then
        If (polycrv.IsClosed() And polycrv.Ispolyline() > 3) Then Return True
      End If
 
      ' is it a [[rhino:nurbs|NURBs]] curve that looks like a polyline?
      Dim crv As IOnCurve = OnCurve.ConstCast(geom)
      If (crv IsNot Nothing) Then
        Dim n As New OnNurbsCurve()
        If (crv.GetNurbForm(n) > 0) Then
          If (n.IsClosed() And n.IsPolyline() > 3) Then Return True
        End If
      End If
    End If
    Return False
  End Function
End Class
 
Public Overrides Function RunCommand(ByVal context As IRhinoCommandContext)_
  As IRhinoCommand.result
 
  Dim go As New CRhGetClosedPolyline()
  go.SetCommandPrompt("Select closed polyline")
  go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.curve_object)
  go.GetObjects(1, 1)
  If (go.CommandResult() = IRhinoCommand.result.success) Then
    ' TODO...
  End If
  Return IRhinoCommand.result.success
End Function

C#

private class CRhGetClosedPolyline : MRhinoGetObject
{
  public override bool CustomGeometryFilter(IRhinoObject rh_object,
                                            IOnGeometry geom,
                                            OnCOMPONENT_INDEX component_index)
  {
    if (geom != null)
    {
      // is it a polyline?
      IOnPolylineCurve polyline = OnPolylineCurve.ConstCast(geom);
      if (polyline != null)
      {
        if (polyline.IsClosed() && polyline.IsPolyline() > 3)
          return true;
      }
      // is it a polycurve that looks like a polyline?
      IOnPolyCurve polycrv = OnPolyCurve.ConstCast(geom);
      if (polycrv != null)
      {
        if (polycrv.IsClosed() && polycrv.IsPolyline() > 3)
          return true;
      }
 
      // is it a [[rhino:nurbs|NURBs]] curve that looks like a polyline?
      IOnCurve crv = OnCurve.ConstCast(geom);
      if (crv != null)
      {
        OnNurbsCurve n = new OnNurbsCurve();
        if (crv.GetNurbForm(ref n) > 0)
        {
          if (n.IsClosed() && n.IsPolyline() > 3)
            return true;
        }
      }
    }
    return false;
  }
}
 
public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
{
  CRhGetClosedPolyline go = new CRhGetClosedPolyline();
  go.SetCommandPrompt("Select closed polyline");
  go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.curve_object);
  go.GetObjects(1, 1);
  if (go.CommandResult() == IRhinoCommand.result.success)
  {
    // TODO...
  }
  return IRhinoCommand.result.success;
}
developer/sdksamples/customgeometryfilter.txt · Last modified: 2010/01/26 16:37 (external edit) Driven by DokuWiki Recent changes RSS feed

 © 1997-2012 

McNeel North America Europe Latin AmericaAsia