McNeel Wiki
Create a Bounding Polyline of a Mesh Object
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++, .NET
VersionRhino 4

Overview

In order to create a mesh object's bounding polyline, you need to find all of the mesh edges that have only a single mesh face. Using the mesh's topology makes this very easy. Note, this functionality is build into Rhino's DupBorder command.

The following sample source code demonstrates how to create a bounding polyline of a mesh object using the Rhino SDK. Note, this code only works on open meshes as closed meshes have no naked edges.

C++

  CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context )
  {
    // Select an open mesh object
    CRhinoGetObject go;
    go.SetCommandPrompt( L"Select open mesh" );
    go.SetGeometryFilter( CRhinoGetObject::mesh_object );
    go.SetGeometryAttributeFilter( CRhinoGetObject::open_mesh );
    go.GetObjects( 1, 1 );
    if( go.CommandResult() != success )
      return go.CommandResult();


    // Validate the selection
    const CRhinoObjRef& ref = go.Object(0);
    const ON_Mesh* mesh = ref.Mesh();
    if( 0 == mesh  )
      return failure;


    // Get the mesh's topology
    const ON_MeshTopology& mesh_top = mesh->Topology();
    ON_SimpleArray<const ON_Curve*> lines( mesh_top.m_tope.Count() );


    // Find all of the mesh edges that have only a single mesh face
    int i;
    for( i = 0; i < mesh_top.m_tope.Count(); i++ )
    {
      const ON_MeshTopologyEdge& mesh_edge = mesh_top.m_tope[i];
      if( mesh_edge.m_topf_count == 1 )
      {
        ON_3fPoint p0 = mesh_top.TopVertexPoint( mesh_edge.m_topvi[0] );
        ON_3fPoint p1 = mesh_top.TopVertexPoint( mesh_edge.m_topvi[1] );
        ON_LineCurve* line = new ON_LineCurve( ON_3dPoint(p0), ON_3dPoint(p1) );
        lines.Append( line );
      }
    }


    ON_SimpleArray<ON_Curve*> output;
    double tolerance = 2.1 * context.m_doc.AbsoluteTolerance();


    // Join all of the line segments
    if( RhinoMergeCurves(lines, output, tolerance) )
    {
      for( i = 0; i < output.Count(); i++ )
      {
        CRhinoCurveObject* crv = new CRhinoCurveObject;
        crv->SetCurve( output[i] );
        if( context.m_doc.AddObject(crv) )
          crv->Select();
        else
          delete crv;
      }
    }


    // Clean up so we don't leak memory
    for( i = 0; i < lines.Count(); i++ )
      delete lines[i];


    return success;
  }

C# (Rhino 4)

  public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
  {
    // Select an open mesh object
    MRhinoGetObject go = new MRhinoGetObject();
    go.SetCommandPrompt( "Select open mesh" );
    go.SetGeometryFilter( IRhinoGetObject.GEOMETRY_TYPE_FILTER.mesh_object );
    go.SetGeometryAttributeFilter( IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.open_mesh );
    go.GetObjects( 1, 1 );
    if( go.CommandResult() != IRhinoCommand.result.success )
      return go.CommandResult();


    // Validate the selection
    IRhinoObjRef objref = go.Object(0);
    IOnMesh mesh = objref.Mesh();
    if( mesh == null )
      return IRhinoCommand.result.failure;


    // Get the mesh's topology
    IOnMeshTopology mesh_top = mesh.Topology();
    List<OnCurve> lines = new List<OnCurve>();


    // Find all of the mesh edges that have only a single mesh face
    IArrayOnMeshTopologyEdge edges = mesh_top.m_tope;
    On3dPoint from = new On3dPoint();
    On3dPoint to = new On3dPoint();
    for( int i = 0; i < edges.Count(); i++ )
    {
      IOnMeshTopologyEdge mesh_edge = edges[i];
      if( mesh_edge.m_topf_count == 1 )
      {
        OnLine line  =new OnLine();
        On3fPoint p0 = mesh_top.TopVertexPoint( mesh_edge.get_m_topvi(0) );
        from.Set(p0.x, p0.y, p0.z);
        On3fPoint p1 = mesh_top.TopVertexPoint( mesh_edge.get_m_topvi(1) );
        to.Set(p1.x, p1.y, p1.z);
        lines.Add( new OnLineCurve( from, to ));
      }
    }


    double join_tol = 2.1 * context.m_doc.AbsoluteTolerance();
    OnCurve[] output = new OnCurve[0];
    if( RhUtil.RhinoMergeCurves( lines.ToArray(), ref output, join_tol) )
    {
      for( int i = 0; i < output.Length; i++ )
      {
        MRhinoCurveObject crv = new MRhinoCurveObject();
        crv.SetCurve( output[i] );
        if( context.m_doc.AddObject( crv ) )
          crv.Select();
      }
    }


    return IRhinoCommand.result.success;
  }

VB.NET (Rhino 4)

  Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) _
    As RMA.Rhino.IRhinoCommand.result
    ' Select an open mesh object
    Dim go As New MRhinoGetObject()
    go.SetCommandPrompt("Select open mesh")
    go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.mesh_object)
    go.SetGeometryAttributeFilter(IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.open_mesh)
    go.GetObjects(1, 1)
    If (go.CommandResult() <> IRhinoCommand.result.success) Then
      Return go.CommandResult()
    End If


    ' Validate the selection
    Dim objref As IRhinoObjRef = go.Object(0)
    Dim mesh As IOnMesh = objref.Mesh()
    If (mesh Is Nothing) Then Return IRhinoCommand.result.failure


    ' Get the mesh's topology
    Dim mesh_top As IOnMeshTopology = mesh.Topology()
    Dim lines As New List(Of OnCurve)()


    ' Find all of the mesh edges that have only a single mesh face
    Dim edges As IArrayOnMeshTopologyEdge = mesh_top.m_tope
    Dim ptFrom As New On3dPoint()
    Dim ptTo As New On3dPoint()
    For i As Integer = 0 To edges.Count() - 1
      Dim mesh_edge As IOnMeshTopologyEdge = edges(i)
      If (mesh_edge.m_topf_count = 1) Then
        Dim line As New OnLine()
        Dim p0 As On3fPoint = mesh_top.TopVertexPoint(mesh_edge.m_topvi(0))
        ptFrom.Set(p0.x, p0.y, p0.z)
        Dim p1 As On3fPoint = mesh_top.TopVertexPoint(mesh_edge.m_topvi(1))
        ptTo.Set(p1.x, p1.y, p1.z)
        lines.Add(New OnLineCurve(ptFrom, ptTo))
      End If
    Next


    Dim join_tol As Double = 2.1 * context.m_doc.AbsoluteTolerance()
    Dim output(0) As OnCurve
    If (RhUtil.RhinoMergeCurves(lines.ToArray(), output, join_tol)) Then
      For i As Integer = 0 To output.Length - 1
        Dim crv As New MRhinoCurveObject()
        crv.SetCurve(output(i))
        If (context.m_doc.AddObject(crv)) Then
          crv.Select()
        End If
      Next
    End If


    Return IRhinoCommand.result.success
  End Function
rename · changes · history · subscriptions · lost and found · references · file upload