CRhinoCommand::result CCommandSamplePrePostSelect::RunCommand( const CRhinoCommandContext& context )
{
  double dValue = m_dValue;
  int nValue = m_nValue;

  CRhinoGetObject go;
  go.SetGeometryFilter( CRhinoGetObject::curve_object );
  go.EnableGroupSelect( TRUE );
  go.EnableSubObjectSelect( FALSE );

  /*int d_option_index =*/ go.AddCommandOptionNumber( 
      RHCMDOPTNAME(L"Double"), &dValue, L"Double value", FALSE, 1.0, 99.9 );

  /*int n_option_index =*/ go.AddCommandOptionInteger( 
      RHCMDOPTNAME(L"Integer"), &nValue, L"Integer value", 1, 99 );

  bool bHavePreselectedObjects = false;

  for( ;; )
  {
    CRhinoGet::result res = go.GetObjects( 1, 0 );

    if( res == CRhinoGet::option )
    {
      go.EnablePreSelect( FALSE );
      go.EnableAlreadySelectedObjectSelect( true );
      go.EnableClearObjectsOnEntry( false );
      go.EnableDeselectAllBeforePostSelect( false );
      go.EnableUnselectObjectsOnExit( false );
      continue;
    }

    else if( res != CRhinoGet::object )
      return CRhinoCommand::cancel;

    if( go.ObjectsWerePreSelected() )
    {
      bHavePreselectedObjects = true;
      go.EnablePreSelect( FALSE );
      go.EnableAlreadySelectedObjectSelect( true );
      go.EnableClearObjectsOnEntry( false );
      go.EnableDeselectAllBeforePostSelect( false );
      go.EnableUnselectObjectsOnExit( false );
      continue;
    }

    break;
  }

  if( bHavePreselectedObjects )
  {
    // Normally, pre-selected objects will remain selected, when a
    // command finishes, and post-selected objects will be unselected.
    // This this way of picking, it is possible to have a combination
    // of pre-selected and post-selected. So, to make sure everything
    // "looks the same", lets unselect everything before finishing
    // the command.
    for( int i = 0; i < go.ObjectCount(); i++ )
    {
      const CRhinoObject* object = go.Object(i).Object();
      if( 0 != object )
        object->Select( false );
    }
    context.m_doc.Redraw();
  }

  int object_count = go.ObjectCount();
  m_dValue = dValue;
  m_nValue = nValue;

  RhinoApp().Print( L"Select object count = %d\n", object_count );
  RhinoApp().Print( L"Value of double = %f\n", m_dValue );
  RhinoApp().Print( L"Value of integer = %d\n", m_nValue );

  return CRhinoCommand::success;
}
CRhinoCommand::result CCommandTestUVMesh::RunCommand( const CRhinoCommandContext& context )
{
  bool bDeleteInput = false;
  CRhinoGetObject go;
  go.SetCommandPrompt(L"Select untrimmed surface");
  go.AddCommandOptionInteger(RHCMDOPTNAME(L"U"), &m_U, 0, 2);
  go.AddCommandOptionInteger(RHCMDOPTNAME(L"V"), &m_V, 0, 2);
  go.AddCommandOptionToggle(RHCMDOPTNAME(L"DeleteInput"), RHCMDOPTVALUE(L"No"), RHCMDOPTVALUE(L"Yes"), bDeleteInput, &bDeleteInput);
  go.SetGeometryFilter(CRhinoGetObject::surface_object);
  go.SetGeometryAttributeFilter(CRhinoGetObject::untrimmed_surface);

  CRhinoGet::result rs = CRhinoGet::no_result;
  while (CRhinoGet::cancel != rs && CRhinoGet::nothing != rs && CRhinoGet::object != rs)
    rs = go.GetObjects(1,1);

  if (CRhinoGet::cancel == rs)
    return CRhinoCommand::cancel;
  if (0 == go.ObjectCount())
    return CRhinoCommand::failure;

  const CRhinoObject* pObj = go .Object(0).Object();
  if (0 == pObj)
    return CRhinoCommand::failure;

  const ON_BrepFace* pBrepFace = go.Object(0).Face();
  if (0 == pBrepFace)
    return CRhinoCommand::failure;

  const ON_Surface* pSurf = pBrepFace->SurfaceOf();
  if (0 == pSurf)
    return CRhinoCommand::failure;

  ON_SimpleArray<double>UArray(m_U+1);
  ON_SimpleArray<double>VArray(m_V+1);
  double UDist, VDist;
  UDist = (pSurf->Domain(0).m_t[1]-pSurf->Domain(0).m_t[0])/m_U;
  VDist = (pSurf->Domain(1).m_t[1]-pSurf->Domain(1).m_t[0])/m_V;
  int i;
  for (i=0; i <= m_U; i++)
    UArray.Append(pSurf->Domain(0).m_t[0] + i*UDist);
  for (i=0; i <= m_V; i++)
    VArray.Append(pSurf->Domain(1).m_t[0] + i*VDist);

  //If m_U or m_V are large then there can be a slight difference between
  //pSurf->Domain(0).m_t[0] + (m_U-1)*UDist and pSurf->Domain(0).m_t[1]
  //ON_MeshSurface requires it to be less than or equal to pSurf->Domain(0).m_t[1]
  //05/24/06 TimH Fix for RR21194
  double* d = UArray.Last();
  if (pSurf->Domain(0).m_t[1] < *d)
    *d = pSurf->Domain(0).m_t[1];
  d = VArray.Last();
  if (pSurf->Domain(1).m_t[1] < *d)
    *d = pSurf->Domain(1).m_t[1];

  ON_Mesh* pMeshOut = ON_MeshSurface(*pSurf, m_U+1, UArray.Array(), m_V+1, VArray.Array());

  if (0 == pMeshOut)
    return CRhinoCommand::failure;

  CRhinoMeshObject* pMeshObj = new CRhinoMeshObject(pObj->Attributes());
  if (0 == pMeshObj)
  {
    delete pMeshOut;
    return CRhinoCommand::failure;
  }
  pMeshObj->SetMesh(pMeshOut);

  if (true == bDeleteInput)
    context.m_doc.ReplaceObject(pObj, pMeshObj);
  else
    context.m_doc.AddObject(pMeshObj);

  context.m_doc.Redraw();
  return CRhinoCommand::success;
}