McNeel Wiki
How To: Dynamically Draw Geometry when Picking Points
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 new class from CRhinoGetPoint to dynamically draw geometry during a point picking operation.

When using Rhino, you have probably noticed that many of the object creation commands, such as Line and Circle, and transformation commands, such as Move and Copy, dynamically draw objects as they are being created or transformed. This operation is performed by deriving a new class from Rhino's point pick class, CRhinoGetPoint, and overriding two member functions: OnMouseMove() and DynamicDraw().

OnMouseMove() is called every time the mouse moves. This is a great place to perform calculations, such as transformations.

DynamicDraw() is called as the mouse moves, as well. Every time the mouse moves, DynamicDraw() will be called once per viewport. Note, Rhino calls DynamicDraw() happen the call to OnMouseMove().

The following example demonstrates how to derive a new class from CRhinoGetPoint and override OnMouseMove() and DynamicDraw() to dynamically draw geometry. In this example, we are going to dynamically draw a circle while the user is specifying its radius.

C++

First, here is the CRhinoGetPoint derived class declaration and definition:

  class CGetCircleRadiusPoint : public CRhinoGetPoint
  {
  public:
    CGetCircleRadiusPoint();
    void SetCenterPoint( const ON_3dPoint center_point );
    bool CalculateCircle( CRhinoViewport& vp, const ON_3dPoint& pt );


    void OnMouseMove( CRhinoViewport& vp, 
                      UINT flags, 
                      const ON_3dPoint& pt, 
                      const CPoint* pt2d );


    void DynamicDraw( HDC hDC, CRhinoViewport& vp, const ON_3dPoint& pt );
    const ON_Circle& Circle() const;
  private:
    ON_Circle m_circle;
    ON_3dPoint m_center_point;
    bool m_draw_circle;
  };


  CGetCircleRadiusPoint::CGetCircleRadiusPoint()
  {
    m_draw_circle = false;
  }


  void CGetCircleRadiusPoint::SetCenterPoint( const ON_3dPoint center_point )
  {
    m_center_point = center_point;
  }


  bool CGetCircleRadiusPoint::CalculateCircle( CRhinoViewport& vp, const ON_3dPoint& pt )
  {
    double radius = m_center_point.DistanceTo( pt );
    if( radius < ON_SQRT_EPSILON )
      return false;


    ON_Plane plane = vp.ConstructionPlane().m_plane;
    plane.SetOrigin( m_center_point );
    m_circle.Create( plane, radius );
    return m_circle.IsValid() ? true : false;
  }


  void CGetCircleRadiusPoint::OnMouseMove( CRhinoViewport& vp, 
                                           UINT flags, 
                                           const ON_3dPoint& pt,
                                           const CPoint* pt2d )
  {
    m_draw_circle = CalculateCircle( vp, pt );
    CRhinoGetPoint::OnMouseMove( vp, flags, pt, pt2d );
  }


  void CGetCircleRadiusPoint::DynamicDraw( HDC hDC, 
                                           CRhinoViewport& vp, 
                                           const ON_3dPoint& pt )
  {
    if( m_draw_circle )
    {
      ON_Color color = RhinoApp().AppSettings().TrackingColor();
      ON_Color saved_color = vp.SetDrawColor( color );
      vp.DrawCircle( m_circle );
      vp.SetDrawColor( saved_color );
    }
    CRhinoGetPoint::DynamicDraw( hDC, vp, pt );
  }
  const ON_Circle& CGetCircleRadiusPoint::Circle() const
  {
    return m_circle;
  }

Finally, here is our CRhinoGetPoint derived class in action:

  CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
  {
    CRhinoGetPoint gp;
    gp.SetCommandPrompt( L"Center point" );
    gp.ConstrainToConstructionPlane( FALSE );
    gp.GetPoint();
    if( gp.CommandResult() != CRhinoCommand::success )
      return gp.CommandResult();


    ON_3dPoint center_point = gp.Point();


    CGetCircleRadiusPoint gc;
    gc.SetCommandPrompt( L"Radius" );
    gc.ConstrainToConstructionPlane( FALSE );
    gc.SetBasePoint( center_point );
    gc.DrawLineFromPoint( center_point, TRUE );
    gc.SetCenterPoint( center_point );
    gc.GetPoint();
    if( gc.CommandResult() != CRhinoCommand::success )
      return gc.CommandResult();


    if( gc.CalculateCircle( gc.View()->Viewport(), gc.Point() ))
    {
      ON_Circle circle = gc.Circle();
      context.m_doc.AddCurveObject( circle );
      context.m_doc.Redraw();
    }
    return CRhinoCommand::success;
  }

VB.NET (Rhino 4)

First, here is the MRhinoGetPoint derived class declaration and definition:

  Public Class CGetCircleRadiusPoint
    Inherits MRhinoGetPoint


    Private m_circle As OnCircle
    Private m_center_point As On3dPoint
    Private m_draw_circle As Boolean


    Public Sub New()
      m_circle = New OnCircle()
      m_center_point = New On3dPoint()
      m_draw_circle = False
    End Sub


    Public Sub SetCenterPoint(ByVal center_point As IOn3dPoint)
      m_center_point = New On3dPoint(center_point)
    End Sub


    Public Function CalculateCircle(ByVal vp As MRhinoViewport, ByVal pt As IOn3dPoint) _
      As Boolean
      Dim radius As Double = m_center_point.DistanceTo(pt)
      If (radius < OnUtil.On_SQRT_EPSILON) Then Return False


      Dim plane As New OnPlane(vp.ConstructionPlane().m_plane)
      plane.SetOrigin(m_center_point)
      m_circle.Create(plane, radius)
      Return m_circle.IsValid()
    End Function


    Public Overrides Sub OnMouseMove(ByVal vp As MRhinoViewport, _
                                     ByVal nFlags As UInteger, _
                                     ByVal point As IOn3dPoint, _
                                     ByVal view_wnd_point As System.Drawing.Point)
      m_draw_circle = CalculateCircle(vp, point)
      MyBase.OnMouseMove(vp, nFlags, point, view_wnd_point)
    End Sub


    Public Overrides Sub DynamicDraw(ByVal hdc As IntPtr, _
                                     ByVal viewport As MRhinoViewport, _
                                     ByVal pt As IOn3dPoint)
      If (m_draw_circle) Then
        Dim color As OnColor = RhUtil.RhinoApp().AppSettings().TrackingColor()
        Dim saved_color As OnColor = viewport.SetDrawColor(CType(color, UInteger))
        viewport.DrawCircle(m_circle)
        viewport.SetDrawColor(CType(saved_color, UInteger))
      End If
      MyBase.DynamicDraw(hdc, viewport, pt)
    End Sub


    Public Function Circle() As IOnCircle
      Return m_circle
    End Function
  End Class

Finally, here is our MRhinoGetPoint derived class in action:

  Public Overrides Function RunCommand(ByVal context As IRhinoCommandContext) _
    As IRhinoCommand.result


    Dim gp As New MRhinoGetPoint()
    gp.SetCommandPrompt("Center point")
    gp.ConstrainToConstructionPlane(False)
    gp.GetPoint()
    If (gp.CommandResult() <> IRhinoCommand.result.success) Then
      Return gp.CommandResult()
    End If
    Dim center_point As On3dPoint = gp.Point()


    Dim gc As New CGetCircleRadiusPoint()
    gc.SetCommandPrompt("Radius")
    gc.ConstrainToConstructionPlane(False)
    gc.SetBasePoint(center_point)
    gc.DrawLineFromPoint(center_point, True)
    gc.SetCenterPoint(center_point)
    gc.GetPoint()
    If (gc.CommandResult() <> IRhinoCommand.result.success) Then
      Return gc.CommandResult()
    End If


    If (gc.CalculateCircle(gc.View().ActiveViewport(), gc.Point())) Then
      Dim circle As IOnCircle = gc.Circle()
      context.m_doc.AddCurveObject(circle)
      context.m_doc.Redraw()
    End If
    Return IRhinoCommand.result.success
  End Function

C# (Rhino 4)

First, here is the MRhinoGetPoint derived class declaration and definition:

  public class CGetCircleRadiusPoint : MRhinoGetPoint
  {
    private OnCircle m_circle;
    private On3dPoint m_center_point;
    private bool m_draw_circle;


    public CGetCircleRadiusPoint()
    {
      m_circle = new OnCircle();
      m_center_point = new On3dPoint();
      m_draw_circle = false;
    }


    public void SetCenterPoint(IOn3dPoint center_point)
    {
      m_center_point = new On3dPoint(center_point);
    }


    public bool CalculateCircle(MRhinoViewport vp, IOn3dPoint pt)
    {
      double radius = m_center_point.DistanceTo(pt);
      if (radius < OnUtil.On_SQRT_EPSILON)
        return false;


      OnPlane plane = new OnPlane(vp.ConstructionPlane().m_plane);
      plane.SetOrigin(m_center_point);
      m_circle.Create(plane, radius);
      return m_circle.IsValid();
    }


    public override void OnMouseMove(MRhinoViewport vp,
                                     uint nFlags,
                                     IOn3dPoint point,
                                     System.Drawing.Point view_wnd_point)
    {
      m_draw_circle = CalculateCircle(vp, point);
      base.OnMouseMove(vp, nFlags, point, view_wnd_point);
    }


    public override void DynamicDraw(System.IntPtr hdc,
                                     MRhinoViewport viewport,
                                     IOn3dPoint pt)
    {
      if (m_draw_circle)
      {
        OnColor color = RhUtil.RhinoApp().AppSettings().TrackingColor();
        OnColor saved_color = viewport.SetDrawColor(color);
        viewport.DrawCircle(m_circle);
        viewport.SetDrawColor(saved_color);
      }
      base.DynamicDraw(hdc, viewport, pt);
    }


    public IOnCircle Circle()
    {
      return m_circle;
    }
  }

Finally, here is our MRhinoGetPoint derived class in action:

  public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
  {
    MRhinoGetPoint gp = new MRhinoGetPoint();
    gp.SetCommandPrompt("Center point");
    gp.ConstrainToConstructionPlane(false);
    gp.GetPoint();
    if(gp.CommandResult() != IRhinoCommand.result.success)
      return gp.CommandResult();
    On3dPoint center_point = gp.Point();


    CGetCircleRadiusPoint gc = new CGetCircleRadiusPoint();
    gc.SetCommandPrompt("Radius");
    gc.ConstrainToConstructionPlane(false);
    gc.SetBasePoint(center_point);
    gc.DrawLineFromPoint(center_point, true);
    gc.SetCenterPoint(center_point);
    gc.GetPoint();
    if(gc.CommandResult() != IRhinoCommand.result.success)
      return gc.CommandResult();


    if(gc.CalculateCircle(gc.View().ActiveViewport(), gc.Point()))
    {
      IOnCircle circle = gc.Circle();
      context.m_doc.AddCurveObject(circle);
      context.m_doc.Redraw();
    }
    return IRhinoCommand.result.success;
  }
rename · changes · history · subscriptions · lost and found · references · file upload