Sdk Loft
Last changed: dale@mcneel.com-204.177.179.136

.
DeveloperC++, .NET
VersionRhino 4

The following sample code demonstrates how to use the CArgsRhinoLoft class and the RhinoSdkLoftSurface function. The definitions of these can be found in rhinoSdkLoft.h.

Note, this example does not perform any curve sorting or direction matching. This is the responsibility of the the SDK developer.

  CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context )
  {
    // Select curves to loft
    CRhinoGetObject go;
    go.SetCommandPrompt( L"Select curves to loft" );
    go.SetGeometryFilter( CRhinoGetObject::curve_object );
    go.SetGeometryAttributeFilter( CRhinoGetObject::open_curve );
    go.EnableSubObjectSelect( FALSE );
    go.GetObjects( 2, 0 );
    if( go.CommandResult() != CRhinoCommand::success )
      return go.CommandResult();


    // Fill in loft arguments class
    CArgsRhinoLoft args;
    args.m_bAllowStartTangent = FALSE;
    args.m_bAllowEndTangent = FALSE;
    args.m_bUseStartpoint = FALSE;
    args.m_bUseEndpoint = FALSE;
    args.m_bClosed = FALSE;
    args.m_loft_type = CArgsRhinoLoft::ltTight;
    args.m_simplify_method = CArgsRhinoLoft::lsNone;
    args.m_start_condition = CArgsRhinoLoft::leNatural;
    args.m_end_condition = CArgsRhinoLoft::leNatural;
    args.m_rebuild_point_count = 10;
    args.m_refit_tolerance = context.m_doc.AbsoluteTolerance();


    int i, object_count = go.ObjectCount();
    args.m_loftcurves.SetCapacity( object_count );


    // Add loft curves
    for( i = 0; i < object_count; i++ )
    {
      const ON_Curve* curve = go.Object(i).Curve();
      if( curve )
      {
        CRhinoLoftCurve* loft_curve = new CRhinoLoftCurve;
        loft_curve->m_curve = curve->DuplicateCurve();
        loft_curve->m_curve->RemoveShortSegments( ON_ZERO_TOLERANCE, true );
        loft_curve->m_pick_point = ON_UNSET_POINT;
        loft_curve->m_pick_t = ON_UNSET_VALUE;
        loft_curve->m_trim = 0;
        loft_curve->m_bClosed = 
            loft_curve->m_curve->IsClosed() ? true : false;
        loft_curve->m_bPlanar =
            loft_curve->m_curve->IsPlanar(&loft_curve->m_plane)? true : false;
        args.m_loftcurves.Append( loft_curve );
      }
    }


    // Do the loft operation
    ON_SimpleArray<ON_NurbsSurface*> surface_list;
    bool rc = RhinoSdkLoftSurface( args, surface_list );


    // Delete the loft curves used in the surface calculation
    for( i = 0; i < args.m_loftcurves.Count(); i++ )
      delete args.m_loftcurves[i];
    args.m_loftcurves.Empty();


    // If only one surface was calculated, add it to Rhino
    if( surface_list.Count() == 1 )
    {
      CRhinoSurfaceObject* surf_obj = context.m_doc.AddSurfaceObject(*surface_list[0]);


      // AddSurfaceObject make a copy...
      delete surface_list[0];


      if( surf_obj )
        context.m_doc.Redraw();


      return ( surf_obj ? success : failure );
    }


    // If more than one surface was calculated, create a list of breps.
    ON_SimpleArray<ON_Brep*> brep_list;
    for( i = 0; i < surface_list.Count(); i++)
    {
      if( surface_list[i]->IsValid() )
      {
        ON_Brep* brep = ON_Brep::New();
        brep->NewFace( *surface_list[i] );
        delete surface_list[i];
        brep_list.Append( brep );
      }
    }


    // Try joining all breps
    ON_Brep* brep = RhinoJoinBreps( brep_list, context.m_doc.AbsoluteTolerance() );
    if( brep )
    {
      CRhinoBrepObject* brep_object = context.m_doc.AddBrepObject( *brep );


      // AddBrepObject makes a copy...
      delete brep;


      if( brep_object )
        context.m_doc.Redraw();


      return ( brep_object ? success : failure );
    }


    // Othewise just add the individual breps to Rhino.
    for( i = 0; i < brep_list.Count(); i++ )
    {
      if( brep_list[i] )
      {
        CRhinoBrepObject* brep_object = context.m_doc.AddBrepObject( *brep_list[i] );


        // AddBrepObject make a copy...
        delete brep_list[i];
      }
    }


    context.m_doc.Redraw();


    return CRhinoCommand::success;
  }

VB.NET (Rhino 4)

  Public Overrides Function RunCommand(ByVal context As IRhinoCommandContext) _
    As IRhinoCommand.result
    ' Select curves to loft
    Dim go As New MRhinoGetObject()
    go.SetCommandPrompt("Select curves to loft")
    go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.curve_object)
    go.SetGeometryAttributeFilter(IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.open_curve)
    go.EnableSubObjectSelect(False)
    go.GetObjects(2, 0)
    If (go.CommandResult() <> IRhinoCommand.result.success) Then
      Return go.CommandResult()
    End If


    ' Fill in loft arguments class
    Dim args As New MArgsRhinoLoft()
    args.m_bAllowStartTangent = False
    args.m_bAllowEndTangent = False
    args.m_bUseStartpoint = False
    args.m_bUseEndpoint = False
    args.m_bClosed = False
    args.m_loft_type = IArgsRhinoLoft.eLoftType.ltTight
    args.m_simplify_method = IArgsRhinoLoft.eLoftSimplify.lsNone
    args.m_start_condition = IArgsRhinoLoft.eLoftEnds.leNatural
    args.m_end_condition = IArgsRhinoLoft.eLoftEnds.leNatural
    args.m_rebuild_point_count = 10
    args.m_refit_tolerance = context.m_doc.AbsoluteTolerance()


    Dim object_count As Integer = go.ObjectCount()
    Dim loftcurves(object_count - 1) As MRhinoLoftCurve


    ' Add loft curves
    For i As Integer = 0 To object_count - 1
      Dim curve As IOnCurve = go.Object(i).Curve()
      If (curve IsNot Nothing) Then
        loftcurves(i) = New MRhinoLoftCurve()
        loftcurves(i).m_curve = curve.DuplicateCurve()
        loftcurves(i).m_curve.RemoveShortSegments(OnUtil.On_ZERO_TOLERANCE, True)
        loftcurves(i).m_pick_point = New On3dPoint(OnUtil.On_UNSET_POINT)
        loftcurves(i).m_pick_t = OnUtil.On_UNSET_VALUE
        loftcurves(i).m_trim = Nothing
        loftcurves(i).m_bClosed = loftcurves(i).m_curve.IsClosed()
        loftcurves(i).m_bPlanar = loftcurves(i).m_curve.IsPlanar(loftcurves(i).m_plane)
      End If
    Next
    args.m_loftcurves = loftcurves


    'Do the loft operation
    Dim surface_list(0) As OnNurbsSurface
    Dim rc As Boolean = RhUtil.RhinoSdkLoftSurface(args, surface_list)


    ' If only one surface was calculated, add it to Rhino
    If (surface_list.Length = 1) Then
      Dim so As MRhinoSurfaceObject = context.m_doc.AddSurfaceObject(surface_list(0))
      context.m_doc.Redraw()
      If (so IsNot Nothing) Then Return IRhinoCommand.result.success
      Return IRhinoCommand.result.failure
    End If


    ' If more than one surface was calculated, create a list of breps.
    Dim brep_list As New System.Collections.Generic.List(Of OnBrep)
    For i As Integer = 0 To surface_list.Length
      If (surface_list(i).IsValid()) Then
        Dim newbrep As New OnBrep()
        newbrep.NewFace(surface_list(i))
        brep_list.Add(newbrep)
      End If
    Next


    ' Try joining all breps
    Dim brep As OnBrep = RhUtil.RhinoJoinBreps(brep_list.ToArray(), _
                                               context.m_doc.AbsoluteTolerance())
    If (brep IsNot Nothing) Then
      Dim brep_object As MRhinoBrepObject = context.m_doc.AddBrepObject(brep)
      context.m_doc.Redraw()
      If (brep_object IsNot Nothing) Then Return IRhinoCommand.result.success
      Return IRhinoCommand.result.failure
    End If


    ' Othewise just add the individual breps to Rhino.
    For i As Integer = 0 To brep_list.Count - 1
      context.m_doc.AddBrepObject(brep_list(i))
    Next
    context.m_doc.Redraw()
    Return IRhinoCommand.result.success
  End Function

C# (Rhino 4)

  public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
  {
    // Select curves to loft
    MRhinoGetObject go = new MRhinoGetObject();
    go.SetCommandPrompt("Select curves to loft");
    go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.curve_object);
    go.SetGeometryAttributeFilter(IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.open_curve);
    go.EnableSubObjectSelect(false);
    go.GetObjects(2, 0);
    if( go.CommandResult() != IRhinoCommand.result.success )
      return go.CommandResult();


    // Fill in loft arguments class
    MArgsRhinoLoft args = new MArgsRhinoLoft();
    args.m_bAllowStartTangent = false;
    args.m_bAllowEndTangent = false;
    args.m_bUseStartpoint = false;
    args.m_bUseEndpoint = false;
    args.m_bClosed = false;
    args.m_loft_type = (int)IArgsRhinoLoft.eLoftType.ltTight;
    args.m_simplify_method = (int)IArgsRhinoLoft.eLoftSimplify.lsNone;
    args.m_start_condition = (int)IArgsRhinoLoft.eLoftEnds.leNatural;
    args.m_end_condition = (int)IArgsRhinoLoft.eLoftEnds.leNatural;
    args.m_rebuild_point_count = 10;
    args.m_refit_tolerance = context.m_doc.AbsoluteTolerance();


    int object_count = go.ObjectCount();
    MRhinoLoftCurve[] loftcurves = new MRhinoLoftCurve[object_count];


    // Add loft curves
    for( int i=0; i<object_count; i++)
    {
      IOnCurve curve = go.Object(i).Curve();
      if( curve != null )
      {
        loftcurves[i] = new MRhinoLoftCurve();
        loftcurves[i].m_curve = curve.DuplicateCurve();
        loftcurves[i].m_curve.RemoveShortSegments(OnUtil.On_ZERO_TOLERANCE, true);
        loftcurves[i].m_pick_point = new On3dPoint(OnUtil.On_UNSET_POINT);
        loftcurves[i].m_pick_t = OnUtil.On_UNSET_VALUE;
        loftcurves[i].m_trim = null;
        loftcurves[i].m_bClosed = loftcurves[i].m_curve.IsClosed();
        loftcurves[i].m_bPlanar = loftcurves[i].m_curve.IsPlanar(loftcurves[i].m_plane);
      }
    }
    args.m_loftcurves = loftcurves;


    // Do the loft operation
    OnNurbsSurface[] surface_list = null;
    bool rc = RhUtil.RhinoSdkLoftSurface( args, out surface_list);


    if( surface_list == null || surface_list.Length == 0 )
      return IRhinoCommand.result.cancel;


    // If only one surface was calculated, add it to Rhino
    if( surface_list.Length == 1 )
    {
      MRhinoSurfaceObject so = context.m_doc.AddSurfaceObject( surface_list[0] );
      context.m_doc.Redraw();
      if( so == null )
        return IRhinoCommand.result.failure;
      return IRhinoCommand.result.success;
    }


    // If more than one surface was calculated, create a list of breps.
    System.Collections.Generic.List<OnBrep> brep_list =
                  new System.Collections.Generic.List<OnBrep>();
    for( int i=0; i<surface_list.Length; i++ )
    {
      if( surface_list[i].IsValid() )
      {
        OnBrep newbrep = new OnBrep();
        newbrep.NewFace(surface_list[i]);
        brep_list.Add(newbrep);
      }
    }


    // Try joining all breps
    OnBrep brep = RhUtil.RhinoJoinBreps(brep_list.ToArray(),
                                        context.m_doc.AbsoluteTolerance());
    if( brep != null )
    {
      MRhinoBrepObject brep_object = context.m_doc.AddBrepObject(brep);
      context.m_doc.Redraw();
      if( brep_object == null )
        return IRhinoCommand.result.failure;
      return IRhinoCommand.result.success;
    }


    // Othewise just add the individual breps to Rhino.
    for( int i=0; i<brep_list.Count; i++ )
      context.m_doc.AddBrepObject( brep_list[i] );


    context.m_doc.Redraw();
    return IRhinoCommand.result.success;
  }