Site Tools


Non-Interactive Object Selection

Developer: .NET
Summary: Demonstrates how select objects without user intervention.
Notice: The Rhino.NET SDK is deprecated in Rhino 5. A similar example adapted for the new RhinoCommon SDK is available here.

Question

How can I select an object in a non-interactive way? In other words, given the coordinates of a point or a rectangle in which the object is contained, how can I perform the selection? For AutoCAD's AutoLISP users, something like (ssget p) or (ssget p1 p2)?

Answer

This is roughly equivalent to the AutoLISP (ssget p) statement:

VB.NET

  Public Function SSGET_POINT(ByVal doc As MRhinoDoc, ByVal view As MRhinoView, ByVal point As On3dPoint, ByRef pick_list As MRhinoObjRefArray) As Integer
 
    Dim active_vp As MRhinoViewport = view.ActiveViewport()
    Dim world_to_screen As New OnXform()
    active_vp.VP().GetXform(IOn.coordinate_system.world_cs, IOn.coordinate_system.screen_cs, world_to_screen)
    point.Transform(world_to_screen)
 
    Dim pick_context As New MRhinoPickContext()
    pick_context.View = view
    pick_context.Style = IRhinoPickContext.pick_style.point_pick
    pick_context.SkipSelected = False
    pick_context.SkipUnselected = False
    pick_context.PickGroups = True
 
    Dim pick_x As Integer = CInt(point.x)
    Dim pick_y As Integer = CInt(point.y)
    If (active_vp.GetPickXform(pick_x, pick_y, pick_context.PickRegion.m_xform) = False) Then
      Return -1
    End If
 
    active_vp.VP().GetFrustumLine(pick_x, pick_y, pick_context.PickChord)
    pick_context.UpdateClippingPlanes()
    Dim pick_count As Integer = doc.PickObjects(pick_context, pick_list)
 
    Return pick_count
 
  End Function

And, this is roughly equivalent to the AutoLISP (ssget p1 p2) statement:

  Public Function SSGET_WINDOW(ByVal doc As MRhinoDoc, ByVal view As MRhinoView, ByVal point0 As On3dPoint, ByVal point1 As On3dPoint, ByRef pick_list As MRhinoObjRefArray) As Integer
 
    Dim active_vp As MRhinoViewport = view.ActiveViewport()
    Dim world_to_screen As New OnXform()
    active_vp.VP().GetXform(IOn.coordinate_system.world_cs, IOn.coordinate_system.screen_cs, world_to_screen)
    point0.Transform(world_to_screen)
    point1.Transform(world_to_screen)
 
    Dim pick_context As New MRhinoPickContext()
    pick_context.View = view
    pick_context.Style = IRhinoPickContext.pick_style.window_pick
    pick_context.SkipSelected = False
    pick_context.SkipUnselected = False
    pick_context.PickGroups = False
 
    Dim pick_rect As New System.Drawing.Rectangle(CInt(point0.x), CInt(point0.y), CInt(point1.x), CInt(point1.y))
    If (active_vp.GetPickXform(pick_rect, pick_context.PickRegion.m_xform) = False) Then
      Return -1
    End If
 
    active_vp.VP().GetFrustumLine((point1.x + point0.x) / 2, (point1.y + point0.y) / 2, pick_context.PickChord)
    pick_context.UpdateClippingPlanes()
    Dim pick_count As Integer = doc.PickObjects(pick_context, pick_list)
 
    Return pick_count
 
  End Function

The above can be used as follows:

  Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) As RMA.Rhino.IRhinoCommand.result
 
    Dim gp As New MRhinoGetPoint()
    gp.SetCommandPrompt("Pick a selection point")
    gp.GetPoint()
    If (gp.CommandResult() <> IRhinoCommand.result.success) Then
      Return gp.CommandResult()
    End If
 
    Dim point As On3dPoint = gp.Point()
    Dim view As MRhinoView = gp.View()
    If (point Is Nothing Or view Is Nothing) Then
      Return IRhinoCommand.result.failure
    End If
 
    Dim pick_list As New MRhinoObjRefArray()
    Dim pick_count As Integer = SSGET_POINT(context.m_doc, view, point, pick_list)
    If (pick_count <= 0) Then
      RhUtil.RhinoApp().Print("No objects selected." + vbCrLf)
      Return IRhinoCommand.result.nothing
    End If
 
    Dim selected_count As Integer = 0
    Dim pick_object As IRhinoObject = Nothing
    For Each pick_item As MRhinoObjRef In pick_list
      pick_object = pick_item.Object()
      If (pick_object IsNot Nothing AndAlso pick_object.IsSelectable(True)) Then
        pick_object.Select(True)
        selected_count = selected_count + 1
      End If
    Next
 
    If (selected_count > 0) Then
      RhUtil.RhinoApp().Print(String.Format("{0} object(s) selected." + vbCrLf, selected_count))
      context.m_doc.Redraw()
    End If
 
    Return IRhinoCommand.result.success
 
  End Function


developer/sdksamples/ssget.txt ยท Last modified: 2016/03/22 by sandy