Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

developer:sdksamples:meshdrawing [2015/09/14] (current)
Line 1: Line 1:
 +====== Drawing Meshes ======
 +> **Developer:​** //​[[developer:​dotnetplugins|.NET]]//​
 +> **Summary:​** //​Demonstrates how to draw a mesh using a display conduit.//
 +> **NOTICE:** //The Rhino.NET SDK is deprecated in Rhino 5.  This example adapted for the new RhinoCommon SDK is [[developer:​rhinocommonsamples:​meshdrawing|here]]//​
 +=====Question=====
 +Is it possible to create, in .NET, some graphic objects which are not Rhino objects?
 +
 +=====Answer=====
 +Yes. The solution is to use a display conduit to draw. For an overview of display conduits, See **[[DisplayConduitIntroduction.|Display Conduit Introduction]]**
 +
 +=====Example=====
 +In the following we will dynamically draw a mesh. The first thing we need a display conduit to draw the mesh for us. Considering the following class:
 +
 +==== C# ====
 +<code c#>
 +public class DrawBlueMeshConduit : MRhinoDisplayConduit
 +{
 +  private OnMesh m_mesh = null;
 +  private OnColor m_drawing_color = null;
 +  private MDisplayPipelineMaterial m_material = null;
 +  private OnBoundingBox m_mesh_bbox = null;
 +
 +  public DrawBlueMeshConduit(OnMesh mesh)
 +    : base(new MSupportChannels(MSupportChannels.SC_CALCBOUNDINGBOX | MSupportChannels.SC_PREDRAWOBJECTS),​ false)
 +  {
 +    // set up as much data as possible so we do the minimum amount of work possible inside the
 +    // actual display code
 +    m_mesh = mesh;
 +    m_drawing_color = OnColor.FromColor(System.Drawing.Color.Blue);​
 +    m_material = new MDisplayPipelineMaterial();​
 +    m_material.m_FrontMaterial.m_diffuse = m_drawing_color;​
 +    if (m_mesh != null && m_mesh.IsValid())
 +      m_mesh_bbox = m_mesh.BoundingBox();​
 +  }
 +
 +  public override bool ExecConduit(ref MRhinoDisplayPipeline dp, uint nChannel, ref bool bTerminate)
 +  {
 +    if (m_mesh_bbox == null)
 +      return true;
 +
 +    // this is called every frame inside the drawing code so try to do as little as possible
 +    // in order to not degrade display speed. Don't create new objects if you don't have to as this
 +    // will incur an overhead on the heap and garbage collection.
 +
 +    if (nChannel == MSupportChannels.SC_CALCBOUNDINGBOX)
 +    {
 +      // Since we are dynamically drawing geometry, we needed to override
 +      // SC_CALCBOUNDINGBOX. Otherwise, there is a good chance that our
 +      // dynamically drawing geometry would get clipped.
 +
 +      // Union the mesh's bbox with the scene'​s bounding box
 +      m_pChannelAttrs.m_BoundingBox.Union(m_mesh_bbox);​
 +    }
 +    else if (nChannel == MSupportChannels.SC_PREDRAWOBJECTS)
 +    {
 +      // Time to draw our mesh
 +
 +      // Get the active viewport
 +      MRhinoViewport vp = dp.GetRhinoVP();​
 +      if (vp.DisplayMode() == IOn.display_mode.wireframe_display)
 +      {
 +        // If the viewport is in wireframe, draw a wireframe mesh
 +        dp.DrawWireframeMesh(m_mesh,​ m_drawing_color);​
 +      }
 +      else
 +      {
 +        // Otherwise, draw a shaded mesh
 +        dp.DrawShadedMesh(m_mesh,​ m_material);​
 +      }
 +    }
 +    return true;
 +  }
 +}
 +</​code>​
 +
 +==== VB.NET ====
 +<code vb>
 +Public Class DrawBlueMeshConduit
 +  Inherits MRhinoDisplayConduit
 +
 +Private m_mesh As OnMesh = Nothing
 +Private m_drawing_color As OnColor = Nothing
 +Private m_material As MDisplayPipelineMaterial = Nothing
 +Private m_mesh_bbox As OnBoundingBox = Nothing
 +
 +Public Sub New(ByVal mesh As OnMesh)
 +  MyBase.New(New MSupportChannels(MSupportChannels.SC_CALCBOUNDINGBOX Or MSupportChannels.SC_PREDRAWOBJECTS),​ False)
 +
 +  ' set up as much data as possible so we do the minimum amount of work possible inside the
 +  ' actual display code
 +  m_mesh = mesh
 +  m_drawing_color = OnColor.FromColor(System.Drawing.Color.Blue)
 +  m_material = New MDisplayPipelineMaterial()
 +  m_material.m_FrontMaterial.m_diffuse = m_drawing_color
 +  If (m_mesh IsNot Nothing AndAlso m_mesh.IsValid()) Then
 +    m_mesh_bbox = m_mesh.BoundingBox()
 +  End If
 +End Sub
 +
 +Public Overrides Function ExecConduit(ByRef pipeline As RMA.Rhino.MRhinoDisplayPipeline,​ ByVal channel As UInteger, ByRef terminate As Boolean) As Boolean
 +  If (m_mesh_bbox Is Nothing) Then Return True
 +
 +  ' this is called every frame inside the drawing code so try to do as little as possible
 +  ' in order to not degrade display speed. Don't create new objects if you don't have to as this
 +  ' will incur an overhead on the heap and garbage collection.
 +  If (channel = MSupportChannels.SC_CALCBOUNDINGBOX) Then
 +    ' Since we are dynamically drawing geometry, we needed to override
 +    ' SC_CALCBOUNDINGBOX. Otherwise, there is a good chance that our
 +    ' dynamically drawing geometry would get clipped.
 +
 +    ' Union the mesh's bbox with the scene'​s bounding box
 +    m_pChannelAttrs.m_BoundingBox.Union(m_mesh_bbox)
 +  ElseIf (channel = MSupportChannels.SC_PREDRAWOBJECTS) Then
 +    ' Time to draw our mesh
 +
 +    ' Get the active viewport
 +    Dim vp As MRhinoViewport = pipeline.GetRhinoVP()
 +    If (vp.DisplayMode() = IOn.display_mode.wireframe_display) Then
 +      ' If the viewport is in wireframe, draw a wireframe mesh
 +      pipeline.DrawWireframeMesh(m_mesh,​ m_drawing_color)
 +    Else
 +      ' Otherwise, draw a shaded mesh
 +      pipeline.DrawShadedMesh(m_mesh,​ m_material)
 +    End If
 +  End If
 +  Return True
 +End Function
 +
 +End Class
 +</​code>​
 +
 +=====More Information=====
 +Here we have an **MRhinoDisplayConduit** derived class. The constructor of the class requires that we define when we want Rhino to call our display conduit. In this case, we want to be called to be called to ensure the drawing bounding box is the correct size (**MSupportChannels.SC_CALCBOUNDINGBOX**) and when Rhino is drawing visible, non-highlighted objects (**MSupportChannels.SC_PREDRAWOBJECTS**). All **MRhinoDisplayConduit** derived class are required to override the **ExecConduit** abstract member function. This is were all of the action will take place.
 +
 +To use the above class, we can write a simple command, such as the following that creates a meshed sphere and then draws it with our conduit:
 +
 +==== C# ====
 +<code c#>
 +public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
 +{
 +  // Define the sphere
 +  OnSphere sphere = new OnSphere();
 +  MArgsRhinoGetSphere args = new MArgsRhinoGetSphere();​
 +  IRhinoCommand.result rc = RhUtil.RhinoGetSphere(args,​ ref sphere);
 +  if (rc != IRhinoCommand.result.success)
 +    return rc;
 +
 +  // Create a mesh sphere
 +  OnMesh mesh = RhUtil.RhinoMeshSphere( sphere, 10, 10 );
 +  if( mesh == null )
 +    return IRhinoCommand.result.failure;​
 +
 +  // Create an instance of our conduit
 +  DrawBlueMeshConduit conduit = new DrawBlueMeshConduit(mesh);​
 +  // Enable the conduit - don't for get to regen
 +  conduit.Enable();​
 +  context.m_doc.Regen();​
 +
 +  // Pause so the user can see our work
 +  MRhinoGetString gs = new MRhinoGetString();​
 +  gs.SetCommandPrompt("​Press <​Enter>​ to continue"​);​
 +  gs.AcceptNothing();​
 +  gs.GetString();​
 +
 +  // Disable the conduit - don't for get to regen
 +  conduit.Disable();​
 +  context.m_doc.Regen();​
 +
 +  return IRhinoCommand.result.success;​
 + }
 +</​code>​
 +
 +==== VB.NET ====
 +<code vb>
 +Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) _
 +  As RMA.Rhino.IRhinoCommand.result
 +  ' Define the sphere
 +  Dim sphere As New OnSphere()
 +  Dim args As New MArgsRhinoGetSphere()
 +  Dim rc As IRhinoCommand.result = RhUtil.RhinoGetSphere(args,​ sphere)
 +  If (rc <> IRhinoCommand.result.success) Then Return rc
 +
 +  ' Create a mesh sphere
 +  Dim mesh As OnMesh = RhUtil.RhinoMeshSphere(sphere,​ 10, 10)
 +  If (mesh Is Nothing) Then Return IRhinoCommand.result.failure
 +
 +  ' Create an instance of our conduit
 +  Dim conduit As New DrawBlueMeshConduit(mesh)
 +  ' Enable the conduit - don't for get to regen
 +  conduit.Enable()
 +  context.m_doc.Regen()
 +
 +  ' Pause so the user can see our work
 +  Dim gs As New MRhinoGetString()
 +  gs.SetCommandPrompt("​Press <​Enter>​ to continue"​)
 +  gs.AcceptNothing()
 +  gs.GetString()
 +
 +  ' Disable the conduit - don't for get to regen
 +  conduit.Disable()
 +  context.m_doc.Regen()
 +  conduit.Dispose()
 +  Return IRhinoCommand.result.success
 +End Function
 +
 +</​code>​
 +
 +\\
 +
 +{{tag>​Developer dotnet}}
  
developer/sdksamples/meshdrawing.txt ยท Last modified: 2015/09/14 (external edit)