Sdk Draw String
Last changed: -204.177.179.116

.
SummaryDemonstrates how to dynamically draw text strings using the Rhino SDK.

Overview

On occasion, it is useful to dynamically display some text while in the middle of a point picking operation. Rhino's VariableFilletSrf command is a good example of a command that does this.

In order to add this capability to an SDK command, you will need to:

  1. Derive a new class from CRhinoGetPoint.
  2. Override the CRhinoGetPoint::DynamicDraw virtual function.
  3. From within the DynamicDraw override, call CRhinoViewport::DrawString.

The following example code demonstrates how to derive a new class from CRhinoGetPoint, override the CRhinoGetPoint::DynamicDraw member, and draw text dynamically.

C++

  class CDrawStringGetPoint : public CRhinoGetPoint
  {
  public:
    CDrawStringGetPoint() {}
    void DynamicDraw( HDC hdc, CRhinoViewport& vp, const ON_3dPoint& pt );
  };


  void CDrawStringGetPoint::DynamicDraw( HDC hdc, CRhinoViewport& vp, const ON_3dPoint& pt )
  {
    // Format active point as a string
    ON_wString str;
    RhinoFormatPoint( pt, str );


    // Build world-to-screen coordinate transformation
    ON_Xform w2s;
    vp.VP().GetXform( ON::world_cs, ON::screen_cs, w2s );


    // Transform point from world to screen coordinates
    ON_3dPoint screenpoint = w2s * pt;


    // Offset point so text does not overlap cursor
    screenpoint.x += 5.0;
    screenpoint.y += -5.0;


    // Draw string using the system font
    vp.DrawString( str, str.Length(), screenpoint, false, 0, 12, L"System" );


    // Allow base class to draw
    CRhinoGetPoint::DynamicDraw( hdc, vp, pt );
  }

C# (Rhino 4)

  public class CDrawStringGetPoint : MRhinoGetPoint
  {
    public override void  DynamicDraw(System.IntPtr hdc, MRhinoViewport viewport, IOn3dPoint pt)
    {
      MRhinoDisplayPipeline dp = viewport.DisplayPipeline();
      if( dp == null )
        return;


      // get screen point
      On2dPoint screen_pt = dp.Engine().WorldToScreenPoint(pt);


      int x = OnUtil.ON_Round(screen_pt.x);
      int y = OnUtil.ON_Round(screen_pt.y);
      // offset point so text does not overlap cursor
      screen_pt.x += 5.0;
      screen_pt.y -= 5.0;
      string msg = string.Format("screen {0}, {1}", x, y);
      dp.DrawString(msg, viewport.DrawColor(), screen_pt);
      // Allow base class to draw
      base.DynamicDraw(hdc, viewport, pt);
    }
  }

VB.NET (Rhino 4)

 Public Class CDrawStringGetPoint
  Inherits MRhinoGetPoint


  Public Overrides Sub DynamicDraw(ByVal hdc As System.IntPtr, _
                                   ByVal viewport As RMA.Rhino.MRhinoViewport, _
                                   ByVal pt As RMA.OpenNURBS.IOn3dPoint)
    Dim dp As MRhinoDisplayPipeline = viewport.DisplayPipeline()
    If (dp Is Nothing) Then Exit Sub


    ' get screen point
    Dim screen_pt As On2dPoint = dp.Engine().WorldToScreenPoint(pt)


    Dim x As Integer = OnUtil.ON_Round(screen_pt.x)
    Dim y As Integer = OnUtil.ON_Round(screen_pt.y)
    ' offset point so text does not overlap cursor
    screen_pt.x += 5.0
    screen_pt.y -= 5.0
    Dim msg As String = String.Format("screen {0}, {1}", x, y)
    dp.DrawString(msg, viewport.DrawColor(), screen_pt)
    ' Allow base class to draw
    MyBase.DynamicDraw(hdc, viewport, pt)
  End Sub
 End Class

Usage

You can use the above class as you would a CRhinoGetPoint object. Just create a new CDrawStringGetPoint object, initialize the class by calling base class members, and call it's GetPoint member. For example:

C++

  CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context )
  {
    CDrawStringGetPoint gp;
    gp.SetCommandPrompt( L"Pick test point" );
    gp.GetPoint();
    if( gp.CommandResult() != success )
      return gp.CommandResult();


    // TODO...


    return success;
  }

C# (Rhino 4)

  public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
  {
    CDrawStringGetPoint gp = new CDrawStringGetPoint();
    gp.SetCommandPrompt( "Pick test point" );
    gp.GetPoint();
    if( gp.CommandResult() != IRhinoCommand.result.success )
      return gp.CommandResult();


    return IRhinoCommand.result.success;
  }

VB.NET (Rhino 4)

  Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) _
    As RMA.Rhino.IRhinoCommand.result
    Dim gp As New CDrawStringGetPoint()
    gp.SetCommandPrompt("Pick test point")
    gp.GetPoint()
    If (gp.CommandResult() <> IRhinoCommand.result.success) Then
      Return gp.CommandResult()
    End If


    Return IRhinoCommand.result.success
  End Function