CRhinoPickContext questions

Hi everybody,
I am trying to emulate the mouse selection in a 3D space with the CRhinoPickContext but I have two problems:

  1. I define an area of selection which approximates a ray cast by a point towards the objects. While the mouse selection stops on the first object crossed, the PickObjects function selects everything in the area. I could do it if I could get the object distance. I think I can have it for some types of objects with functions like PickPoint, PickLine, PickMesh etc… The problem is that there is not a function to pick breps and surfaces.
  2. I would like to enable also brep and surfaces faces and edges selection. I thought m_bSubSelect=true could work but nothing seems to change.
    Ideas?
    Thanks!

Hi @gennaro,

There are a couple of way to filter objects. Here are a couple of samples.

https://github.com/mcneel/rhino-developer-samples/blob/6/cpp/SampleCommands/cmdSampleSelFilter.cpp

https://github.com/mcneel/rhino-developer-samples/blob/6/cpp/SampleCommands/cmdSamplePickContext.cpp

The latter demonstrates sub-object selection.

– Dale

Dale,
Thanks for your reply.

Sorry but I forgot to tell you that I am working on Rhino 5 at the moment. The first example seems not to compile…
I take advance to explain you more clearly what is my problem.

I define a region which approximates a ray starting from a point to select the first object crossed. What I get is shown in the picture below.

But this is what I would like to get.

I was wondering if there is a fast way to do it with pickobject.

Hi @gennaro,

Given this:

static int compare_objref_seldist(const CRhinoObjRef* a, const CRhinoObjRef* b)
{
  double d = a->SelectionDistance() - b->SelectionDistance();
  if (d < 0.0)
    return -1; // a was closer to pick point
  if (d > 0.0)
    return 1;  // b was closer to pick point

  d = a->SelectionDepth() - b->SelectionDepth();
  if (d > 0.0)
    return -1; // a was nearer to the camera
  if (d < 0.0)
    return 1;  // b was nearer to the camera

  return 0;
}

You can then do this:

CRhinoObjRefArray pick_list;
const int pick_count = context.m_doc.PickObjects(pick_context, pick_list);
if (pick_list.Count() > 0)
{
  pick_list.QuickSort(compare_objref_seldist);
  const CRhinoObject* obj = pick_list[0].Object();
  if (nullptr != obj)
  {
    obj->Select(true);
    context.m_doc.Redraw();
  }
}

Does this help?

– Dale

Dale,
it does help… thanks!

I have another issue, though. The filters of the CRhinoGetObject still confuse me (in the second code you posted). My goal is to build a selection routine which would work mainly in shaded mode, able to pick any object and subobject crossed.
I cannot find a combination of filters suitable. I understand that curve filters and face filters are “mutually exclusive” but I would like to have both in shaded mode…
I also tried to build a custom filter to print out info on the object picked but I get the same problems as some objects do not pass through the filter.
I could repeat the selection more than once with different settings but I would like to avoid it.
Do you know any solution?

Hi @gennaro,

I am not quite sure I understand what you want. But in general it is not possible to pick all things all the time. This is why, when you pick, Rhino supports modifier keys such as and . For example, when you pick with no modifier key (outside of a running command), Rhino picks top level objects. And when hold and and then click, Rhino will select sub-objects. You can mimic this behavior by checking the state of modifier keys after the user picks a 2-D pick point and before you call CRhinoDoc::PickObjects. Between these two blocks of code, you can set up the appropriate object select filter.

Does this help?

– Dale

Dale,

in general I would like to have a selection similar to Rhino GUI. If I define an area of selection I would like to have all objects and sub objects for brep mesh and surfaces. For example for a given brep I would like to get edge and faces when the selection area crosses the edge, but also, I want to select the face when the area crosses just the face. The first is easy. I can set the edge filters and extract the faces from the edge object. But if I set the edge filters I do not get the faces when the edges are not in the selection area. In few words, at the moment I should trigger the PickObjects more than once with different settings to get everything. Am I doing something wrong maybe?

Gennaro

If I’m understanding this correctly you do need to call PickObjects more than once. The picking code is set to prefer edge picks over face picks to feel right when used interactively, so if you do need to get both at the same time, you will need to call PickObjects twice with different settings.

I understand. I will proceed this way!
Thank you all!