Select Objects Without User Interaction Using C++ API

rhino-for-windows

(Chris Rafuse) #1

Hi all,

I need to have an object selected prior to executing a command. I need to do this from within my CRhinoCommand::RunCommand method without any user interaction (no mouse selection from user with CRhinoGetObject). The object will be in a specific layer.

I understand you can get CRhinoObject* from CRhinoDoc::LookupObject, but it’s not clear how to set the state of the objects to selected using these pointers.

Any help would be appreciated.


(Dale Fugier) #2

Hi @chris.rafuse,

In general, you will want to use a CRhinoGetObject object to get pre- or post-selected objects.

CRhinoGetObject go;
go.SetCommandPrompt(L"Select object");
go.EnablePreSelect(TRUE, TRUE);
go.EnableSubObjectSelect(FALSE);
go.GetObjects(1, 1);
if (go.CommandResult() == CRhinoCommand::success)
{
  const CRhinoObject* rh_obj = go.Object(0).Object();
  if (nullptr != rh_obj)
  {
    // TODO...
  }
}

To set the object selection state, use CRhinoGetObject::Select.

– Dale


(Chris Rafuse) #3

Hi Dale,

I may have missed something: The intention is to select from RunCommand without having to get the user to select with the mouse.

The idea is basically to get a pointer to the CRhinoObject* for the object and set its state to selected without any user interaction. Is this possible ?


(Dale Fugier) #4

Hi @chris.rafuse,

Have you tried the code above?

When EnablePreSelect is set to true, then if pre-select objects available and pass the selection filter, provided by the object getter, then the object will be ‘selected’ and the user will not be prompted to pick anything.

– Dale


(Chris Rafuse) #5

I did try it and exactly as above and it prompted the user to select the object with the mouse.

No objects will be selected prior to running the command: the command will be responsible for selecting an object based on its layer.


(Dale Fugier) #6

Hi @chris.rafuse,

Note, I’ve moved this thread to the Rhino Developer category.

OK, for some reason that was not clear. This is probably more like what you are looking for.

CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
  int selected_count = 0;
  const wchar_t* layer_name = L"Default";
  const int layer_index = context.m_doc.m_layer_table.FindLayerFromFullPathName(layer_name, ON_UNSET_INT_INDEX);
  if (layer_index != ON_UNSET_INT_INDEX)
  {
    const CRhinoLayer& layer = context.m_doc.m_layer_table[layer_index];
    if (!layer.IsDeleted())
    {
      ON_SimpleArray<CRhinoObject*> objects;
      const int object_count = context.m_doc.LookupObject(layer, objects);
      if (object_count > 0)
      {
        for (int i = 0; i < object_count; i++)
        {
          const CRhinoObject* obj = objects[i];
          if (nullptr != obj && obj->IsSelectable())
          {
            obj->Select(true);
            selected_count++;
          }
        }
      }
    }
  }

  if (selected_count > 0)
    context.m_doc.Redraw();

  RhinoApp().Print(L"Selected layer objects = %d\n", selected_count);

  return CRhinoCommand::success;
}

– Dale


(Chris Rafuse) #7

Thanks, Dale. That worked.

I did look at CRhinoObject::Select, but the documentation says “Reports if an object can be selected.”. I should have tried it anyways.

Very helpful.