Problem
Imagine you are trying to wrote code to pick grip objects, and you want that only grips at the boundary of a mesh to be selectable. You might have just spent a considerable amount of time trying to get the following to work:
- Derive a class from
CRhinoGetObject
. - Override
CRhinoGetObject::CustomGeometryFilter
.
What is missing is a pointer to a grip object inside CRhinoGetObject::CustomGeometryFilter
. One might think this code would work…
CMyGetObject go; go.SetGeometryFilter( CRhinoGetObject::grip_object );
but now CRhinoGetObject::CustomGeometryFilter
override is not even called anymore. On the other hand, if you do not specify a CRhinoGetObject::SetGeometryFilter
up front, the function is called but you don’t get any grip object from the geometry parameter of CRhinoGetObject::CustomGeometryFilter
.
Is there a way around this problem?
Solution
Yes. In order 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... }
Regarding 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; }