developer:sdksamples:offsetcrvonsrf


Offsetting Curves on Surfaces

C++

Summary: Demonstrates how to offset a curve on a surface using the Rhino SDK.

Question

I am using RhinoOffsetCurveOnSrf SDK function to offset a curve which was interpolated on a cylindrical surface. The problem is that the results do not seem to match those of Rhino's OffsetCrvOnSrf command. That is, the offset curve do not extend to the edges of the surfaces. Why is this?

Answer

After calculating the offset curve, the OffsetCrvOnSrf command extends both ends of that curve to edge of the surface using RhinoExtendCrvOnSrf. Below is an example of how you can do this using the SDK:

CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context )
{
  // Select curve on surface
  CRhinoGetObject gc;
  gc.SetCommandPrompt( L"Select curve on surface" );
  gc.SetGeometryFilter( CRhinoGetObject::curve_object );
  gc.GetObjects( 1, 1 );
  if( gc.CommandResult() != CRhinoCommand::success )
    return gc.CommandResult();
 
  // Validate curve
  const ON_Curve* crv = gc.Object(0).Curve();
  if( 0 == crv )
    return CRhinoCommand::failure;
 
  // Select base surface
  CRhinoGetObject gs;
  gs.SetCommandPrompt( L"Select base surface" );
  gs.SetGeometryFilter( CRhinoGetObject::surface_object );
  gs.EnablePreSelect( false );
  gs.EnableDeselectAllBeforePostSelect( false );
  gs.GetObjects( 1, 1 );
  if( gs.CommandResult() != CRhinoCommand::success )
    return gs.CommandResult();
 
  // Validate face
  const ON_BrepFace* face = gs.Object(0).Face();
  if( 0 == face )
    return CRhinoCommand::failure;
 
  // Validate brep
  const ON_Brep* brep = face->Brep();
  if( 0 == brep )
    return CRhinoCommand::failure;
 
  // Specify offset distance
  CRhinoGetNumber gd;
  gd.SetCommandPrompt( L"Offset distance" );
  gd.SetDefaultNumber( 1.0 );
  gd.GetNumber();
  if( gd.CommandResult() != CRhinoCommand::success )
    return gd.CommandResult();
 
  double dist = gd.Number();
 
  // Do offset curve on surface
  double tol = context.m_doc.AbsoluteTolerance();
  ON_SimpleArray<ON_Curve*> offset_curves;
  CRhinoCommand::result cmdrc = RhinoOffsetCurveOnSrf( crv, brep, face->m_face_index, dist, tol, offset_curves );
  if( cmdrc == CRhinoCommand::success )
  {
    int i = 0;
    ON_SimpleArray<const ON_Curve*> curves_to_join;
    curves_to_join.Append( offset_curves.Count(), offset_curves.Array() );
 
    // Try joining the offset curves
    ON_SimpleArray<ON_Curve*> joined_curves;
    BOOL rc = RhinoMergeCurves( curves_to_join, joined_curves, 2.0 * tol, TRUE );
 
    for( i = 0; i < curves_to_join.Count(); i++ )
      curves_to_join[i] = 0;
 
    if( rc )
    {
      for( i = 0; i < joined_curves.Count(); i++ )
      {
        ON_Curve* pC = joined_curves[i];
        if( pC )
        {
          // Extend both ends to edge of the surface
          if( !pC->IsClosed() )
            RhinoExtendCrvOnSrf( *face, pC );
 
          // Add to document
          CRhinoCurveObject* crv_obj = new CRhinoCurveObject();
          crv_obj->SetCurve( pC );
          context.m_doc.AddObject( crv_obj );
 
          joined_curves[i] = 0;
        }
      }
 
      // Do not leak memory
      for( i = 0; i < offset_curves.Count(); i++ )
      {
        if( offset_curves[i] )
        {
          delete offset_curves[i];
          offset_curves[i] = 0;
        }
      }
    }
    else 
    {
      for( i = 0; i < offset_curves.Count(); i++)
      {
        ON_Curve* pC = offset_curves[i];
        if( pC )
        {
          // Extend both ends to edge of the surface
          if( !pC->IsClosed() )
            RhinoExtendCrvOnSrf( *face, pC );
 
          // Add to document
          CRhinoCurveObject* crv_obj = new CRhinoCurveObject();
          crv_obj->SetCurve( pC );
          context.m_doc.AddObject( crv_obj );
 
          offset_curves[i] = 0;
        }
      }
    }
  }
 
  context.m_doc.Redraw();
 
  return CRhinoCommand::success;
}
developer/sdksamples/offsetcrvonsrf.txt · Last modified: 2010/01/26 16:37 (external edit) Driven by DokuWiki Recent changes RSS feed

 © 1997-2010 

McNeel North America Europe Latin AmericaAsia