[vtkusers] 3-D coordinates from vtkRenderWindow

Gerald Dalley dalleyg at dma.org
Wed Jul 11 09:02:24 EDT 2001


Here's an excerpt of an example of retreiving the 3D coordinates of a pick
in an MFC dialog box.  If you're using the normal UNIX displays and/or an
MFC document-view structure, it's actually easier than what I've done (e.g.
you don't have to cheat and use PreTranslateMessage).  In my implementation,
pressing the "P" key causes a picking action that requires finding the
object selected.  I wrote this code originally for VTK 2.4, before
interactor styles were around, so there are probably slightly cleaner ways
to do some of what I've shown here.

Hope this helps.

--Gerald Dalley
  dalleyg at ee.eng.ohio-state.edu


----------------8<-------cut here------------------8<--------------------
/* This method allows us to trap keystrokes while in an MFC dialog box.
   In this case, we trap the "p" key and pass it off to the normal VTK
   handler.  If we were using MFC document-view, we'd do this a different
   way (using PreTranslateMessage is cheating and may not work exactly
   correctly when Windows has a non-English keyboard driver or input
   method installed). */
BOOL CRegistrationPickerDlg::PreTranslateMessage(MSG* pMsg)
{
    bool propagateMessage = true;

    switch (pMsg->message)
    {
        case WM_CHAR:
            switch (pMsg->wParam)
            {
                case 'p':
                case 'P':
                    SetWindowLong(this->m_hWnd, GWL_USERDATA,
(long)renWin0);
                    vtkHandleMessage(this->m_hWnd, WM_CHAR, 'p', 0);
                    propagateMessage = false;
                    break;
            }
            break;
    }

    if (propagateMessage) {
	    return CDialog::PreTranslateMessage(pMsg);
    } else {
        return true;
    }
}

/* When creating the window interactor, create the picker object
   that will do our work for us.  Using MFC Dialog as setup, here's
   the chain of events:
	1) User moves mouse over desired object and presses "p"
	2) CRegistrationPickerDlg::PreTranslateMessage gets called
	3) vtkHandleMessage is called
	4) iren0Picked is called
	5) CRegistrationPickerDlg::HandlePick is called (see below)
*/
BOOL CRegistrationPickerDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    ...
    pick0 = vtkCellPicker::New();
        pick0->SetTolerance(0.00001);
    iren0 = vtkRenderWindowInteractor::New();
        iren0->SetPicker(pick0);
        iren0->SetEndPickMethod(iren0Picked, this);
    ...

    return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

/* This is the function that will be called when "p" has been pressed.
   We use it here simply as a wrapper for calling the
   CRegistrationPickerDlg::HandlePick method. */
void iren0Picked(void *dlg) {
    CRegistrationPickerDlg *me = (CRegistrationPickerDlg*)dlg;

    me->HandlePick();
}

/* This actually handles the picking operation.  I've left in a little
   extra code because VTK gives you the closest picked point to the
   camera that falls within the tolerance.  I needed a different criterion
   for deciding which point to actually pick.  */
void CRegistrationPickerDlg::HandlePick()
{
    int ptId;

    vtkCellPicker *picker;
    vtkPointSet *input;
    vtkRenderer *renderer;
    vtkRenderWindow *renWin;

    picker = ((vtkCellPicker*)this->iren0->GetPicker());
    input = this->input0;
    renderer = this->renderer0;
    renWin = this->renWin0;

    float *center = picker->GetPickPosition();

    int cellId = picker->GetCellId();

    // We can't just use the SubId to pick the point, because VTK
    // tends to give us the point closest to the *camera*, not the
    // point closest to the point of intersection with the cell.
    if (cellId >= 0) {
        ptId = -1;
        float distSquared;
        float closestDistSquared = VTK_FLOAT_MAX;
        My3Point *closestPoint = NULL;

        vtkCell *pickedCell = input->GetCell(cellId);
        My3Point *point;
        int *idInCell = pickedCell->GetPointIds()->GetPointer(0);
        int numIds = pickedCell->GetNumberOfPoints();
        for (int subId=0; subId<numIds; subId++)
        {
            point = allPoints + (*idInCell);

            distSquared =
                vtkMath::Distance2BetweenPoints(center, (float*)point);

            if (distSquared < closestDistSquared)
            {
                closestDistSquared = distSquared;
                ptId = *idInCell;
                closestPoint = point;
            }

            idInCell++;
        }

        if (this->InputBeingPicked == 0) {
            // "Picked" the background
            ...
        } else {
            // Picked a valid object
            ...
        }
    }

    renWin->Render();
}
----------------8<-------cut here------------------8<--------------------

-----Original Message-----
From: vtkusers-admin at public.kitware.com
[mailto:vtkusers-admin at public.kitware.com]On Behalf Of Jeff Stoll
Sent: Tuesday, 10 July 2001 4:12 PM
To: vtkusers at public.kitware.com
Subject: [vtkusers] 3-D coordinates from vtkRenderWindow


To all vtk users:

   So I have been doing a web search and have  come across some ideas
but I can't seem to get anything to work.  Here is the problem, which
seems to be a fairly popular problem.  I am trying to use the mouse to
both manipulate the render window (zoom, pan, rotate) and also use it to
click on actors in the render window and get their x,y, and z
coordinates.  Unfortuneately I don't know how to get the mouse to become
a 2 fold interactor, and I don't know how to get the x,y and z
coordinates.  I know this must be an easy question to many of you out
there, please help an inexperiance VTK user if you can.  Please email
responses to busds at bu.edu

Shaun Selha
Dept. Aerospace and Mechanical Engineering
Boston University


_______________________________________________
This is the private VTK discussion list.
Please keep messages on-topic. Check the FAQ at:
<http://public.kitware.com/cgi-bin/vtkfaq>
Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/vtkusers





More information about the vtkusers mailing list