I am using vtkCellPicker
in my project, and I find it unexpected work.
The code to reproduce my problem is:
import vtk
lineSource = vtk.vtkLineSource()
lineSource.SetPoint1(0, 0, 0)
lineSource.SetPoint2(512, 512, 0)
lineSource.Update()
lineMapper = vtk.vtkPolyDataMapper()
lineMapper.SetInputData(lineSource.GetOutput())
lineActor = vtk.vtkActor()
lineActor.SetMapper(lineMapper)
lineActor.GetProperty().SetColor(255, 0, 0)
lineActor.GetProperty().SetLineWidth(10)
pointPolyData = vtk.vtkPolyData()
pointPolyData.SetPoints(vtk.vtkPoints())
pointPolyData.SetVerts(vtk.vtkCellArray())
pointPolyData.GetPoints().InsertNextPoint(0, 0, 0)
pointPolyData.GetVerts().InsertNextCell(1)
pointPolyData.GetVerts().InsertCellPoint(0)
pointMapper = vtk.vtkPolyDataMapper()
pointMapper.SetInputData(pointPolyData)
pointActor = vtk.vtkActor()
pointActor.SetMapper(pointMapper)
pointActor.GetProperty().SetColor(255, 255, 0)
pointActor.GetProperty().SetPointSize(10)
pointActor.GetProperty().SetRepresentationToPoints()
pointActor.GetProperty().RenderPointsAsSpheresOn()
renderer = vtk.vtkRenderer()
renderer.AddActor(lineActor) ########################### order
renderer.AddActor(pointActor) ##########################
renderer.SetBackground(0.4, 0.5, 0.6)
renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer(renderer)
renderWindow.Render()
def mousemove(iren, even):
pos = iren.GetEventPosition()
picker = vtk.vtkCellPicker()
picker.SetTolerance(0.05)
picker.Pick(pos[0], pos[1], 0, renderer)
actor = picker.GetProp3D()
if actor == lineActor:
print('line')
elif actor == pointActor:
print('point')
else:
print('none')
renderWindowInteractor = vtk.vtkRenderWindowInteractor()
renderWindowInteractor.AddObserver("MouseMoveEvent", mousemove)
style = vtk.vtkInteractorStyleImage()
renderWindowInteractor.SetInteractorStyle(style)
renderWindowInteractor.SetRenderWindow(renderWindow)
renderWindowInteractor.Initialize()
renderWindowInteractor.Start()
Please have a look for the following figure:
In the above figure, I can pick the point
in the white arrow. However, I can only pick line
for the blue arrow, but I expect the blue arrow can pick the point
.
I find it may be caused by the order to add point
and line
. If I change the order to:
renderer.AddActor(pointActor)
renderer.AddActor(lineActor)
It can pick point
and 'line` as what I expect.
However, in my thought, the order to add point
/line
should have no effect for my situation. Because, the position of blue arrow is more close to the point
than the line
.
Then, I have a look into c++ code. After debug, I find vtkCellPicker
actually picked both point
and line
, and add it to Prop3Ds
(vtkPicker.cxx line 689
).
Then, in the GetViewProp
, it return this->Path->GetFirstNode()->GetViewProp()
, it only return the first node rather than to calculate the distance between picked prop and pick position.
How can I do to pick the point
at the position of blue arrow?
Any suggestion is appreciated~~~