McNeel Wiki
Splitting a Curve into Multiple Curve Segments
edit · print · help · all topics
Main Pages

AccuRender

Bongo

Brazil r/s

Developer

Flamingo

Penguin

Rhino Blogs

Rhino

Search

Languages

Česky

Deutsch

English

Español

Français

Italiano

Polish

日本語

한국어

中文(繁體)

 
.
DeveloperC++
SummaryDemonstrates how to split a curve into multiple curve segments using the Rhino SDK.

Question

I know that I can use ON_Curve::Split to split a curve into two pieces. But, how to split a curve into multiple curve segments based on an array of curve parameters?

Answer

The solution is to call ON_TrimCurve repeatedly using the source curve as input. ON_TrimCurve will create new curves based on a specified interval of a source curve.

For example:

C++

  CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context )
  {
    // Select curve to split
          CRhinoGetObject go;
    go.SetCommandPrompt( L"Select curve to split" );
    go.SetGeometryFilter( CRhinoGetObject::curve_object );
    go.GetObjects( 1, 1 );
    if( go.CommandResult() != success )
      return go.CommandResult();


    // Validate selection
    const CRhinoObjRef& crv_obj_ref = go.Object(0);
    const CRhinoObject* crv_obj = crv_obj_ref.Object();
    const ON_Curve* crv = crv_obj_ref.Curve();
    if( 0 == crv_obj || 0 == crv )
      return failure;


    // Number of segments to create
    CRhinoGetInteger gi;
    gi.SetCommandPrompt( L"Number of segments to create" );
    gi.SetLowerLimit( 2 );
    gi.SetUpperLimit( 100 );
    gi.GetInteger();
    if( gi.CommandResult() != success )
      return gi.CommandResult();


    int num_segments = gi.Number();


    // Generate an array of curve parameters where
    // the splitting will occur.
    ON_SimpleArray<double> curve_t( num_segments );
    bool rc = RhinoDivideCurve( *crv, num_segments, 0, false, true, 0, &curve_t );
    if( !rc )
    {
      RhinoApp().Print( L"Error dividing curve into segments.\n" );
      return failure;
    }


    // If the curve is closed, append the ending domain parameter
    ON_Interval dom = crv->Domain();
    if( crv->IsClosed() )
      curve_t.Append( dom.m_t[1] );


    ON_3dmObjectAttributes atts( crv_obj->Attributes() );


    // Do the splitting (or should I say trimming...)
    int i;
    for( i = 0; i < curve_t.Count() - 1; i++ )
    {
      // Build an interval to trim
      ON_Interval interval( curve_t[i], curve_t[i+1] );
      if( dom.Includes(interval) )
      {
        // Do the trim
        ON_Curve* new_crv = ON_TrimCurve( *crv, interval );
        if( new_crv )
        {
          // Add the "trimmed" curve
          CRhinoCurveObject* new_crv_obj = new CRhinoCurveObject( atts );
          new_crv_obj->SetCurve( new_crv );
          context.m_doc.AddObject( new_crv_obj );
        }
      }
    }


    // Delete the original object
    context.m_doc.DeleteObject( crv_obj_ref );
    context.m_doc.Redraw();


    return success;
  }
rename · changes · history · subscriptions · lost and found · references · file upload