Python 如何使用vtk选择直线中的点?

Python 如何使用vtk选择直线中的点?,python,pyqt,vtk,Python,Pyqt,Vtk,在VTK中,我有一个曲面和一条线,而这条线包含在曲面中。然后,我需要在直线上选择一个点。我实现了自己的Interactiver,并通过右键单击获得世界坐标。我希望选择点可以位于线路中。释放右键时,我会在渲染器中显示选定的行。但是,我发现我无法选择线中的点。我的代码是: import vtk, os, sys import numpy as np from PyQt5.QtWidgets import * from vtk.qt.QVTKRenderWindowInteractor import

在VTK中,我有一个曲面和一条线,而这条线包含在曲面中。然后,我需要在直线上选择一个点。我实现了自己的Interactiver,并通过右键单击获得世界坐标。我希望选择点可以位于线路中。释放右键时,我会在渲染器中显示选定的行。但是,我发现我无法选择线中的点。我的代码是:

import vtk, os, sys
import numpy as np
from PyQt5.QtWidgets import *
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from vtk.util.numpy_support import vtk_to_numpy, numpy_to_vtk

def numpyToVtk(data, type=vtk.VTK_FLOAT):
    flat_data_array = data.transpose(2,1,0).flatten()
    vtk_data_array = numpy_to_vtk(flat_data_array)
    vtk_data = numpy_to_vtk(num_array=vtk_data_array, deep=True, array_type=type)
    img = vtk.vtkImageData()
    img.GetPointData().SetScalars(vtk_data)
    img.SetDimensions(data.shape)
    img.SetOrigin(0, 0, 0)
    img.SetSpacing(1, 1, 1)
    return img

class ourInteractor(vtk.vtkInteractorStyleTrackballCamera):

    def __init__(self, renderer=None, renWindow=None):
        super(ourInteractor, self).__init__()
        self.AddObserver("RightButtonReleaseEvent", self.OnRightButtonUp)
        self.ren = renderer
        self.renWin = renWindow

    def OnRightButtonUp(self, obj, event):
        super(ourInteractor, self).OnRightButtonUp()
        pos = self.GetInteractor().GetEventPosition()
        coordinate = vtk.vtkCoordinate()
        coordinate.SetCoordinateSystemToDisplay()
        coordinate.SetValue(pos[0], pos[1], 0)
        worldCoor = coordinate.GetComputedWorldValue(
            self.GetInteractor().GetRenderWindow().GetRenderers().GetFirstRenderer())
        print('screen coor: ', pos, 'world coor: ', worldCoor)
        points = vtk.vtkPoints()
        vertices = vtk.vtkCellArray()
        id = points.InsertNextPoint(worldCoor[0], worldCoor[1], worldCoor[2])
        vertices.InsertNextCell(1)
        vertices.InsertCellPoint(id)
        point = vtk.vtkPolyData()
        point.SetPoints(points)
        point.SetVerts(vertices)
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputData(point)
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)
        actor.GetProperty().SetPointSize(10)
        actor.GetProperty().SetColor(0, 1, 0)
        self.ren.AddActor(actor)
        self.renWin.Render()

class AirwaySkeleton(QMainWindow):

    def __init__(self, parent=None):
        super(AirwaySkeleton, self).__init__(parent=parent)
        self.setWindowTitle("Airway Skeleton")
        widget = QWidget()
        self.setCentralWidget(widget)
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        widget.setLayout(layout)
        self.mainLayout = layout

        frame = QFrame()
        vtkWidget = QVTKRenderWindowInteractor(frame)
        self.mainLayout.addWidget(vtkWidget)

        ren = vtk.vtkRenderer()
        vtkWidget.GetRenderWindow().AddRenderer(ren)
        iren = vtkWidget.GetRenderWindow().GetInteractor()
        style = ourInteractor(renderer=ren, renWindow=vtkWidget.GetRenderWindow())
        iren.SetInteractorStyle(style)
        ren.SetBackground(0, 0, 0)

        self.ren = ren

        mask = np.zeros(shape=[200, 200, 200], dtype=np.uint8)
        mask[20:80, 50:150, 50:150] = 1
        mask[80:150, 80:120, 80:120] = 1
        mask[150:170, 50:150, 50:150] = 1

        xs = np.arange(20, 170, 0.1)
        line = []
        for x in xs:
            line.append([x, 100, 100])
        actors = self.createActorsForLines([np.array(line)])
        vtkMask = numpyToVtk(data=mask, type=vtk.VTK_CHAR)
        mesh = self.maskToMesh(vtkMask)

        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(mesh.GetOutputPort())
        mapper.ScalarVisibilityOff()

        actor = vtk.vtkLODActor()
        actor.SetMapper(mapper)
        actor.GetProperty().SetColor(1, 1, 1)
        actor.GetProperty().SetOpacity(0.4)

        self.ren.AddActor(actor)
        for lineActor in actors:
            self.ren.AddActor(lineActor)

        self.renWin = vtkWidget.GetRenderWindow()
        iren.Initialize()
        self.iren = iren

    def maskToMesh(self, mask):
        contour = vtk.vtkDiscreteMarchingCubes()
        contour.SetInputData(mask)
        contour.SetValue(0, 1)
        contour.Update()

        smoother = vtk.vtkWindowedSincPolyDataFilter()
        smoother.SetInputConnection(contour.GetOutputPort())
        smoother.SetNumberOfIterations(30)
        smoother.BoundarySmoothingOff()
        smoother.NonManifoldSmoothingOn()
        smoother.NormalizeCoordinatesOn()
        smoother.Update()

        triangleCellNormals = vtk.vtkPolyDataNormals()
        triangleCellNormals.SetInputConnection(smoother.GetOutputPort())
        triangleCellNormals.ComputeCellNormalsOn()
        triangleCellNormals.ComputePointNormalsOff()
        triangleCellNormals.ConsistencyOn()
        triangleCellNormals.AutoOrientNormalsOn()
        triangleCellNormals.Update()

        return triangleCellNormals

    def createActorsForLines(self, lines):
        actors = []
        endPoints = vtk.vtkPoints()
        for line in lines:
            n = line.shape[0]
            endPoints.InsertNextPoint(line[0, 0], line[0, 1], line[0, 2])
            endPoints.InsertNextPoint(line[-1, 0], line[-1, 1], line[-1, 2])
            points = vtk.vtkPoints()
            vtkLines = vtk.vtkCellArray()
            vtkLines.InsertNextCell(n)
            for i in range(n):
                points.InsertNextPoint(line[i, 0], line[i, 1], line[i, 2])
                vtkLines.InsertCellPoint(i)

            polygonPolyData = vtk.vtkPolyData()
            polygonPolyData.SetPoints(points)
            polygonPolyData.SetLines(vtkLines)

            mapper = vtk.vtkPolyDataMapper()
            mapper.SetInputData(polygonPolyData)
            actor = vtk.vtkActor()
            actor.SetMapper(mapper)
            actor.GetProperty().SetColor(1, 0, 0)
            actors.append(actor)
        polyData = vtk.vtkPolyData()
        polyData.SetPoints(endPoints)
        sphereSource = vtk.vtkSphereSource()
        sphereSource.SetRadius(1)
        glyph3D = vtk.vtkGlyph3D()
        glyph3D.SetSourceConnection(sphereSource.GetOutputPort())
        glyph3D.SetInputData(polyData)
        glyph3D.Update()
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(glyph3D.GetOutputPort())
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)
        actor.GetProperty().SetColor(0, 0, 1)
        actors.append(actor)
        return actors


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = AirwaySkeleton()
    window.show()
    sys.exit(app.exec_())
我的代码怎么了?任何建议都将不胜感激! 此外,如何在曲面中拾取点?

解决方案很简单:

从vtkplotter导入* 将numpy作为np导入 掩码=np.zerosshape=[200200],数据类型=np.uint8 遮罩[20:80,50:150,50:150]=1 掩码[80:150,80:120,80:120]=1 遮罩[150:170,50:150,50:150]=1 vol=Volumemask返回vtkVolume iso=vol.isosurfacethreshold=1.c“灰色”。alpha0.3.pickable0 平滑的\u iso=iso。平滑拉普拉斯指数=30 直线=线路20100100、170100100、lw=10 VTK def onLeftClickmesh: 打印单击的三维点:,mesh.picked3d,c='红色' vp.addSpherepos=mesh.picked3d,r=2,c=绿色 vp=绘图仪详细信息=0,轴=8,bg='黑色' vp.mouseLeftClickFunction=onLeftClick 艾琳·肖乌·伊索副总裁 可以嵌入以下示例中

解决方案很简单:

从vtkplotter导入* 将numpy作为np导入 掩码=np.zerosshape=[200200],数据类型=np.uint8 遮罩[20:80,50:150,50:150]=1 掩码[80:150,80:120,80:120]=1 遮罩[150:170,50:150,50:150]=1 vol=Volumemask返回vtkVolume iso=vol.isosurfacethreshold=1.c“灰色”。alpha0.3.pickable0 平滑的\u iso=iso。平滑拉普拉斯指数=30 直线=线路20100100、170100100、lw=10 VTK def onLeftClickmesh: 打印单击的三维点:,mesh.picked3d,c='红色' vp.addSpherepos=mesh.picked3d,r=2,c=绿色 vp=绘图仪详细信息=0,轴=8,bg='黑色' vp.mouseLeftClickFunction=onLeftClick 艾琳·肖乌·伊索副总裁 可以嵌入以下示例中


非常感谢你!此外,如何拾取曲面中的点?是的,您可以使用pickablemethod。您还可以为此添加更多的键盘回调。谢谢mmusy。但是,如果卷被初始化为:mask=np.zerosshape=[200200500],dtype=np.uint8,我发现它无法提取等值面。你知道为什么吗?非常感谢!此外,如何拾取曲面中的点?是的,您可以使用pickablemethod。您还可以为此添加更多的键盘回调。谢谢mmusy。但是,如果卷被初始化为:mask=np.zerosshape=[200200500],dtype=np.uint8,我发现它无法提取等值面。你知道为什么吗?