Site Tools


Custom Picking of Grip Objects

Developer: C++
Summary: Discusses how to write a custom grip object picker

Question

I have just spent considerable time trying to get the following to work:

  1. Derive a class from CRhinoGetObject.
  2. Override CRhinoGetObject::CustomGeometryFilter.

I want only grips at the boundary of a mesh to be selectable. I have methods to do this. I just need to get a pointer to a grip object inside CRhinoGetObject::CustomGeometryFilter. If I do:

CMyGetObject go;
go.SetGeometryFilter( CRhinoGetObject::grip_object );

my CRhinoGetObject::CustomGeometryFilter override is not even called anymore. If I do not specify a CRhinoGetObject::SetGeometryFilter up front, the function is called but I don't get any grip object from the geometry parameter of CRhinoGetObject::CustomGeometryFilter.

Is there a way around this problem?

Answer

To pick grip objects using CRhinoGetObject you must set the CRhinoGetObject::grip_object geometry filter. If not, then Rhino will ignore grips in an effort to improve picking performance.

Also, if you want your CRhinoGetObject::CustomGeometryFilter override to be called, make sure to call CRhinoGetObject::EnableSubObjectSelect to disable subobject picking. For example:

CMyGetObject go;
go.SetGeometryFilter( CRhinoObject::grip_object );
go.EnableSubObjectSelect( false );
go.GetObjects( 1, 0 );
if( go.CommandResult() == CRhinoCommand::success )
{
  // TODO...
}

For the picking of grips at the boundary of a mesh, here is a sample class that you can use.

class CRhGetMeshBoundaryGrip : public CRhinoGetObject
{
public:
  bool CustomGeometryFilter( 
    const CRhinoObject* obj, 
    const ON_Geometry* geo, 
    ON_COMPONENT_INDEX ci 
    ) const;
};
 
bool CRhGetMeshBoundaryGrip::CustomGeometryFilter( 
  const CRhinoObject* obj, 
  const ON_Geometry* geo, 
  ON_COMPONENT_INDEX ci 
  ) const
{
  if( 0 == obj )
    return false;
 
  // Is grip object?
  const CRhinoGripObject* grip_obj = CRhinoGripObject::Cast( obj );
  if( 0 == grip_obj )
    return false;
 
  // Is mesh grip object?
  const CRhinoMeshObject* mesh_obj = CRhinoMeshObject::Cast( grip_obj->Owner() );
  if( 0 == mesh_obj )
    return false;
 
  // Is the grip on the border?
  const ON_Mesh* mesh = mesh_obj->Mesh();
  if( mesh && !mesh->IsClosed() )
  {
    const ON_MeshTopology& meshtop = mesh->Topology();
    int topvi = meshtop.m_topv_map[grip_obj->m_grip_index];
    const ON_MeshTopologyVertex& topv = meshtop.m_topv[topvi];
    for( int i = 0; i < topv.m_tope_count; i++ )
    {
      const ON_MeshTopologyEdge& tope = meshtop.m_tope[topv.m_topei[i]];
      if( 1 == tope.m_topf_count )
        return true;
    }
  }
 
  return false;
}


developer/sdksamples/customgripselection.txt ยท Last modified: 2020/08/14 (external edit)