Table of Contents
Splitting a Curve into Multiple Curve Segments
C++
Summary: Demonstrates 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; }