[vtkusers] picking on a surface

John Hunter jdhunter at ace.bsd.uchicago.edu
Wed Apr 7 11:59:31 EDT 2004


I would like to interactively select points on a surface.  Ultimately,
I want to do this with surfaces constructed from marching cubes
algorithm on medical data, but I am practicing by trying to select
points on the surface of the sphere.  In my example below (cell
picker) the selected points appear either on the surface of the sphere
or at the very center, but the points selected (which I mark with a
smaller sphere) seem to bear no relation to the place where I click.

Questions:

  * what should the z value for the pick location be?  

  * why is the center of the sphere sometimes picked?

  * My goal is for the picker to shoot a ray from my cursor position
    into the render window orthogonal to the plane of my monitor, and
    return the cell id of the closest polygon in the data set.  This
    does not seem to be happening.  What am I doing wrong?


Here is a complete example using the python wrapper

#!/usr/bin/env python

import vtk

renderer = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(renderer)
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(renWin)

sphere = vtk.vtkSphereSource()
sphere.SetRadius(20)
res = 20
sphere.SetThetaResolution(res)
sphere.SetPhiResolution(res)
sphere.SetCenter(0,0,0)
mapper = vtk.vtkPolyDataMapper()
mapper.SetInput(sphere.GetOutput())

actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetOpacity(0.5)

renderer.AddActor(actor)

def mark(x,y,z):
    """mark the picked location with a sphere"""
    sphere = vtk.vtkSphereSource()
    sphere.SetRadius(1)
    res = 20
    sphere.SetThetaResolution(res)
    sphere.SetPhiResolution(res)
    sphere.SetCenter(x,y,z)
    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInput(sphere.GetOutput())

    marker = vtk.vtkActor()
    marker.SetMapper(mapper)
    renderer.AddActor(marker)
    marker.GetProperty().SetColor( (1,0,0) )
    interactor.Render()
    
def pick_cell(renwinInteractor, event):
    x, y = renwinInteractor.GetEventPosition()

    picker = vtk.vtkCellPicker()
    picker.Pick(x, y, 0, renderer)
    vid =  picker.GetCellId()
    if vid!=-1:
        sid = picker.GetSubId()
        pcoords = picker.GetPCoords()
        print vid, sid, pcoords
        dataSet = picker.GetDataSet()
        pnt = dataSet.GetPoint(vid)
        mark(*pnt)
    else:
        print 'swing and a miss'

interactor.AddObserver('LeftButtonPressEvent', pick_cell)


interactor.Initialize()
interactor.Start()





More information about the vtkusers mailing list