Currently, I want to extract the isosurface from a volume image, and I use vtk.vtkMarchingCubes to implement it. Moreover, I want to change the iso-value by mouse. I have implement the code as following:
import vtk, sys
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
val = [1000, None]
def setVal(v):
    val[0] = v
    val[1].SetValue(v)
class MyInteractor(vtk.vtkInteractorStyleTrackballCamera):
    def __init__(self):
        self.AddObserver("LeftButtonPressEvent", self.leftButtonPressEvent)
        self.AddObserver("LeftButtonReleaseEvent", self.leftButtonReleaseEvent)
        self.AddObserver("MouseMoveEvent", self.leftButtonMoveEvent)
        self.btnPress = False
        self.lastPoint = [0, 0]
    def leftButtonPressEvent(self, obj, event):
        self.btnPress = True
        pos = self.GetInteractor().GetEventPosition()
        self.lastPoint = [pos[0], pos[1]]
    def leftButtonReleaseEvent(self, obj, event):
        self.btnPress = False
    def leftButtonMoveEvent(self, obj, event):
        if self.btnPress == True:
            curPos = self.GetInteractor().GetEventPosition()
            dx = curPos[0] - self.lastPoint[0]
            dy = curPos[1] - self.lastPoint[1]
            isoValue = val[0]
            if abs(dx) > abs(dy):
                isoValue += dx
            else:
                isoValue += dy
            setVal(isoValue)
            self.lastPoint = [curPos[0], curPos[1]]
        else:
            super().OnMouseMove()
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=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()
        style = MyInteractor()
        self.iren.SetInteractorStyle(style)
        reader = vtk.vtkDICOMImageReader()
        reader.SetDirectoryName("C:\\Users\\MLoong\\Desktop\\Angiograph Data\\Chang Cheng\\TOF")
        reader.Update()
        surface = vtk.vtkMarchingCubes()
        surface.SetInputConnection(reader.GetOutputPort())
        surface.ComputeNormalsOn()
        surface.SetValue(0, 300)
        surface.Update()
        self.surface = surface
        # Create a mapper
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(surface.GetOutputPort())
        mapper.ScalarVisibilityOff()
        # Create an actor
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)
        actor.GetProperty().SetColor(1, 1, 1)
        actor.GetProperty().ShadingOff()
        self.ren.AddActor(actor)
        self.ren.ResetCamera()
        self.frame.setLayout(self.vl)
        self.setCentralWidget(self.frame)
        self.show()
        self.iren.Initialize()
    def SetValue(self, val):
        print(val)
        self.surface.SetValue(0, val)
        self.surface.Update()
        self.vtkWidget.GetRenderWindow().Render()
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    val[1] = window
    sys.exit(app.exec_())
This code has no bug after provide a correct image in reader.SetDirectoryName(“path”). I can change the iso-value by left mouse press and move. But the problem is that the speed is slow. Does anybody has any suggestion to speed it up?


