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)?
This is roughly equivalent to the AutoLISP (ssget p) statement:
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