Picking Surface Point
Windows only

Problem

You want to pick a point on the surface of an object.

Solution

There are a couple of ways to do this:

  • Use a CRhinoGetObject class.
  • Use a CRhinoGetPoint class.

Using CRhinoGetObject

When picking objects with a CRhinoGetObject object, the CRhinoObjRef returned by the object contains picking information, such as the location of the pick…

CRhinoCommand::result CCommandTestPick1::RunCommand( const CRhinoCommandContext& context )
{
CRhinoGetObject go;
go.SetCommandPrompt( L"Select a surface or a polysurface" );
go.SetGeometryFilter( CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object );
go.EnablePreSelect( FALSE );
go.GetObjects( 1, 1 );
if( go.CommandResult() != CRhinoCommand::success )
return go.CommandResult();
const CRhinoObjRef& ref = go.Object(0);
// If the object was selected by picking a point on it, then
// SelectionPoint() returns true and the point where the selection
// occured.
ON_3dPoint pt;
if( ref.SelectionPoint(pt) )
{
context.m_doc.AddPointObject( pt );
context.m_doc.Redraw();
}
return CRhinoCommand::success;
}

Using CRhinoGetPoint

When picking points with a CRhinoGetPoint object, you can constrain the point picking to a surface…

CRhinoCommand::result CCommandTestPick2::RunCommand( const CRhinoCommandContext& context )
{
CRhinoGetObject go;
go.SetCommandPrompt( L"Select a surface" );
go.SetGeometryFilter( CRhinoGetObject::surface_object );
go.EnablePreSelect( FALSE );
go.GetObjects( 1, 1 );
if( go.CommandResult() != CRhinoCommand::success )
return go.CommandResult();
const CRhinoObjRef& ref = go.Object(0);
const ON_BrepFace* face = ref.Face();
if( 0 == face )
return CRhinoCommand::failure;
CRhinoGetPoint gp;
gp.SetCommandPrompt( L"Select point on surface" );
gp.Constrain( *face );
gp.GetPoint();
if( gp.CommandResult() != CRhinoCommand::success )
return gp.CommandResult();
ON_3dPoint pt = gp.Point();
context.m_doc.AddPointObject( pt );
context.m_doc.Redraw();
return CRhinoCommand::success;
}