I am trying to embed vtk rendering code in PyQt5 with with QVTKRenderWindowInteractor. When I tried to use vtkBoxWidget inside it, program crashed. Without vtkBoxWidget (enclosed within two lines in below code ), its working fine. Can you please help me find the issue? I am trying to manually crop the rendered object using a bounding box with the help of vtkBoxWidget.
CODE:
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QFrame, QVBoxLayout
import sys
import vtk
from PyQt5 import QtGui
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class MainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.frame = QFrame()
self.vl = QVBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.vl.addWidget(self.vtkWidget)
self.ren = vtk.vtkRenderer()
self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
self.iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
# Create source
source = vtk.vtkSphereSource()
source.SetCenter(0, 0, 0)
source.SetRadius(5.0)
# Create a mapper
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(source.GetOutputPort())
# Create an actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
###################################################################################
boxWidget = vtk.vtkBoxWidget()
boxWidget.SetInteractor(self.iren)
boxWidget.SetPlaceFactor(1.0)
boxWidget.SetRotationEnabled(0)
planes = vtk.vtkPlanes()
def ClipVolumeRender(obj, event):
obj.GetPlanes(planes)
mapper.SetClippingPlanes(planes)
boxWidget.SetProp3D(actor)
boxWidget.PlaceWidget()
boxWidget.InsideOutOn()
boxWidget.AddObserver("InteractionEvent", ClipVolumeRender)
boxWidget.On()
###################################################################################
self.ren.AddActor(actor)
self.ren.ResetCamera()
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.show()
self.iren.Initialize()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
The problem is that boxWidget is a local variable that is eliminated by python, so afterwards the application tries to access that object but it no longer has allocated memory generating Segmentation fault. The solution is to extend the scope by changing boxWidget
with self.boxWidget
.