McNeel Wiki
How To: Create a Custom CRhinoGetObject Class
edit · print · help · all topics
Main Pages

AccuRender

Bongo

Brazil r/s

Developer

Flamingo

Penguin

Rhino Blogs

Rhino

Rhino Labs

Search

Languages

Česky

Deutsch

English

Español

Français

Italiano

Polish

日本語

한국어

中文(繁體)

 
.
DeveloperC++, .NET
SummaryDemonstrates 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
  {
    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 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 (Rhino 4)

  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 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# (Rhino 4)

  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 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;
  }
rename · changes · history · subscriptions · lost and found · references · file upload