I’m using a conduit to draw some geometry, and want to be able to select some of what I’ve drawn.
I’ve seen other plug-ins where it is possible, for example, to select mesh vertices or edges.
I want to do something similar, but with points and lines.
What’s the easiest way to do this? Can anyone point me to samples of code for achieving this or similar object picking operations?
I haven’t tried this myself, but what you need to do is convert picked screen coordinate to a world coordinate. Using the world coordinate you can find the geometry that is close to or at that coordinate and perform a “selection” action in your display conduit.
Rhino’s object picking support only extends to objects that are in the document. In other words, the Rhino SDK does not have pre-canned functions that you help you pick dynamically drawn geometry. That said, it is possible to simulate the picking of dynamic drawn geometry. Rhino 5’s Gumball object is a good example of this.
The first think you will need to do is maintain a list of the dynamically drawn geometry. Without one, there is no hope of ever knowing what you picked on.
The next think you will need to do is to construct a pick context (Rhino.Input.Custom.PickContext). Having one of these will provide whatever function you write, that does the actual picking, some useful information on where and how the user picked. I don’t find a lot of examples of using a pick context (because it is hard). But I do have an example of using a custom Gumball object that uses a pick context. Here is the sample of how to construct one:
The real work is in your own picking function, where you get to interpret what is provided by the pick context and see if it hits any of your custom geometry.
Thanks for the suggestions and samples. I have explored both options a bit, although found by doing so that they converged towards the same sort of thing.
Based on the gumball example that Dale provided, I have tried to set up my own pick context as below:
Public Class ConduitPointGetter
Inherits GetPoint
Private points As Point3d()
'The points that are drawn in my conduit, passed to this class when I use it
Public Property PointList() As Point3d()
Get
Return points
End Get
Set(ByVal value As Point3d())
points = value
End Set
End Property
Protected Overrides Sub OnMouseDown(e As Rhino.Input.Custom.GetPointMouseEventArgs)
Dim Picker As New Rhino.Input.Custom.PickContext()
Picker.View = e.Viewport.ParentView
Picker.PickStyle = Rhino.Input.Custom.PickStyle.PointPick
Dim xform As Transform = e.Viewport.GetPickTransform(e.WindowPoint)
Picker.SetPickTransform(xform)
Dim index As New Integer
Dim dpth As New Double
Dim dis As New Double
Picker.PickFrustumTest(Me.PointList, index, dpth, dis)
End Sub
is a way of comparing the point I’ve clicked with the points in my conduit (which I pass to the class by setting the property where I call the method). My assumption however doesn’t correlate with the overloads of PickFrustumTest. Unfortunately there’s some documentation missing in that bit of the SDK.
Before I tried the pick context suggestion, I used Rhino.Input.Custom.GetPoint to get a 3D point, and then, by comparing the distance between that point and all the points in my conduit, figured out which point it was. I also found that I could use GetPoint.ClearSnapPoints and GetPoint.AddSnapPoint/s to ensure that the cursor would only allow me to click on the location of the drawn points. (I could do this with my class above too).
What I can’t immediately see is how to use the pick context that I’ve ended up with. Similarly I can’t figure out how either method could allow me to select multiple drawn points by dragging a rectangle around them (as I could do with points actually in the document).
I think you should make a polyline that will close on right mouse button or enter. Then selboundary the polyline. After this you will have everthing selected within the polyline