Picking point position from a rendered STL

Hello,

I have been using vtk for a project with python. Before I start my question, excuse me if this is not the place to ask about using vtk with python or if this has been asked before. I did some research but couldn’t find any answers.

So I read and render an stl file with my main program, file location is given by the user from a Qt popup window. Then on the surface of the 3d model, I need to get the data of z-axis, along a line that will be drawn after user clicks 2 locations for the line to be drawn. For this purpose I need to extract the position on the surface of the 3d model that is clicked, so that I can draw the line, then with some intervals, I can extract the required information.

I have redefined mouse buttons using vtk example of interactor, as follows:

class MyInteractorStyle(vtk.vtkInteractorStyleTrackballCamera):

def __init__(self, parent=None):
    self.AddObserver("MiddleButtonPressEvent", self.middle_button_press_event)
    self.AddObserver("MiddleButtonReleaseEvent", self.middle_button_release_event)
    self.AddObserver("RightButtonPressEvent", self.right_button_press_event)
    self.AddObserver("RightButtonReleaseEvent", self.right_button_release_event)
    self.AddObserver("LeftButtonPressEvent", self.left_button_press_event)
    self.AddObserver("LeftButtonReleaseEvent", self.left_button_release_event)

Middle and Right buttons just work fine, as before, so here is my left button events.

def left_button_press_event(self, obj, event):
    clickPos = self.GetInteractor().GetEventPosition()
    
    picker = vtk.vtkPropPicker()

    self.NewPickedActor = picker.GetActor()
    picker.Pick(clickPos[0], clickPos[1], 0, self.GetDefaultRenderer())
    pointpos=picker.GetPickPosition()
    
    print("Left Button pressed, position: ", pointpos[0], ' ', pointpos[1], ' ', pointpos[2])
    return

def left_button_release_event(self, obj, event):
    print("Left Button released")
    return

Here is the problem though, I try to print ‘pointpos’ variable, but my qt window shuts down without giving me any errors. What am I doing wrong here ? A C++ example works just fine with this part.

1 Like

I am not sure if needed but, here is the part of the code that I open the stl file.

def getSTLLocation(self): 
    return QtWidgets.QFileDialog.getOpenFileName(self, 'Open File', 'D:\','STL File (*.stl)')

def setSTLFrame(self, file):
    self.stlFrame = QtWidgets.QFrame(self.centralwidget)
    sizePolicy.setHeightForWidth(self.stlFrame.sizePolicy().hasHeightForWidth())
    self.stlFrame.setSizePolicy(sizePolicy)
    self.stlFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
    self.stlFrame.setFrameShadow(QtWidgets.QFrame.Raised)
    self.stlFrame.setObjectName("stlFrame")
    self.MainVerticalLayout.addWidget(self.stlFrame)
    
    self.vl = QtWidgets.QVBoxLayout()
    self.vtkWidget = QVTKRenderWindowInteractor(self.stlFrame)
    self.vl.addWidget(self.vtkWidget)

    self.ren = vtk.vtkRenderer()
    self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
    self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
    
    #==============
    self.vtkWidget.SetInteractorStyle(MyInteractorStyle())
    #===============

    reader = vtk.vtkSTLReader()
    reader.SetFileName(file)

    # Create a mapper
    mapper = vtk.vtkPolyDataMapper()
    if vtk.VTK_MAJOR_VERSION <= 5:
        mapper.SetInput(reader.GetOutput())
    else:
        mapper.SetInputConnection(reader.GetOutputPort())

    # Create an actor
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    
    self.ren.AddActor(actor)

    self.ren.ResetCamera()

    self.stlFrame.setLayout(self.vl)

    self.iren.Initialize()
    self.iren.Start()

It sets a choosen stl model on the Qt frame just fine.

Hi, I came across a similar problem.

After several rounds of test, I realized the problem is because self.GetDefaultRenderer() does not exist.

I solved the problem by adding the following code:

style = MyInteractorStyle()
style.SetDefaultRenderer(self.renderer)
iren.SetInteractorStyle(style)

Please try if this works.

Best,
Shuchun