McNeel Wiki
How To: Dynamically Drawing a Polyline
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++
SummaryDemonstrates how to derive a new class from CRhinoGetPoint to dynamically draw a polyline.

Question

What is the best way to draw dynamically a geometry based on a polyline? Your wiki example Dynamically Draw Geometry When Picking Points draws a circle and modifies the radius when the mouse cursor moves. But how is it possible to compute an object geometry based on a polyline picked by the user?

Answer

If you are not interested in writing your own drawing routine and you want to just use Rhino's built-in polyline drawing tool, then you can just use Rhino's RhinoGetPolyline function. See rhinoSdkGetLine.h for more information.

If you need more control over how the polyline is define or how it is drawn, then you can derive your own class from CRhinoGetPoint and draw the polyline yourself.

The following example code demonstrates a simple class, derived from CRhinoGetPoint, that dynamically draws a polyline based on the points picked by a user.

  /////////////////////////////////////////////////////////////////////////////
  // CRhGetPoints declaration


  class CRhGetPoints : public CRhinoGetPoint
  {
  public:
    CRhGetPoints();
    void DynamicDraw( HDC hdc, CRhinoViewport& vp, const ON_3dPoint& pt );
    CRhinoGet::result GetPoints( CRhinoHistory* history = NULL, bool bOnMouseUp = false );
    int Points( ON_3dPointArray& points );


  public:
    ON_3dPointArray m_P;
  };


  /////////////////////////////////////////////////////////////////////////////
  // CRhGetPoints definition


  CRhGetPoints::CRhGetPoints()
  {
    m_P.SetCapacity( 64 );
  }


  CRhinoGet::result CRhGetPoints::GetPoints( CRhinoHistory* history, bool bOnMouseUp )
  {
    m_P.Empty();


    SetCommandPrompt( L"First point" );


    CRhinoGet::result res = GetPoint( history, bOnMouseUp );


    if( res == CRhinoGet::point )
    {
      m_P.Append( Point() );


      SetCommandPrompt( L"Next point" );
      PermitOrthoSnap();
      AcceptNothing();


      for( ;; )
      {
        SetBasePoint( Point() );


        res = GetPoint( history, bOnMouseUp );


        if( res == CRhinoGet::point )
        {
          m_P.Append( Point() );
          continue;
        }


        else if( res == CRhinoGet::nothing )
          res = CRhinoGet::point;


        else if( res == CRhinoGet::cancel )
          m_P.Empty();


        break;
      }
    }


    return res;
  }


  void CRhGetPoints::DynamicDraw( HDC hdc, CRhinoViewport& v, const ON_3dPoint& pt )
  {
    if( m_P.Count() > 0 )
    {
      int i;
      for( i = 1; i < m_P.Count(); i++ )
      {
        v.DrawPoint( m_P[i-1] );
        v.DrawLine( m_P[i-1], m_P[i] );
      }
      v.DrawPoint( m_P[i-1] );
      v.DrawPoint( pt );
      v.DrawLine( m_P[i-1], pt );
    }
    CRhinoGetPoint::DynamicDraw( hdc, v, pt);
  }


  int CRhGetPoints::Points( ON_3dPointArray& points )
  {
    int count = m_P.Count();
    if( count > 0 )
      points.Append( count, m_P.Array() );
    return count;
  }

You would use the above class as follows:

  CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context )
  {
    CRhGetPoints gp;
    CRhinoGet::result res = gp.GetPoints();
    if( res == CRhinoGet::point )
    {
      // TODO...
    }
    return CRhinoCommand::success;
  }

Some additional features that would make this class better are:

  • The code should evaluate the distance between the current point and the previous point before adding them to the point array to ensure the points are not duplicate.
  • The code should allow for an undo feature.
  • After a few points have been picked, the drawing tends to flicker. This is because the entire polyline is being drawn on every mouse move. To prevent flickering, portions of the polyline that do not need to be drawn on every mouse move should drawn with a conduit.
rename · changes · history · subscriptions · lost and found · references · file upload