如何在带有 vtkPolyDataNormals 的 vtkPolyData vtkCylinderSource 上正常显示?

How display normal on a vtkPolyData vtkCylinderSource with vtkPolyDataNormals?

我正在尝试显示圆柱源每个单元格的法线 vtkCylinderSource。 我正在使用 vtkPolyDataNormals class 和 vtkGlyph3D 但法线未显示在 QT 视图中。 我不明白我做错了什么。 这是我现在使用的代码

from PyQt5.QtWidgets import *
import vtk
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

class Cylinder(QMainWindow):
    def __init__(self, parent=None):
        super(Cylinder, self).__init__( )

        self.parent=parent
        self.frame = QFrame()

        self.vl = QVBoxLayout()
        self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
        self.vl.addWidget(self.vtkWidget)

        self.ren = vtk.vtkRenderer()
        self.ren.SetBackground(.2, .3, .3)
        self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
        self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
        style =vtk.vtkInteractorStyleTrackballCamera( )
        style.SetDefaultRenderer(self.ren)
        self.iren.SetInteractorStyle(style)
        self.ren.ResetCamera()
        self.frame.setLayout(self.vl)
        self.setCentralWidget(self.frame)
        self.show()
        self.iren.Initialize()
        self.iren.Start()

        self.draw_Electrode()

    def set_center(self):
        self.ren.ResetCamera()

    def Render(self, ):
        self.iren.GetRenderWindow().Render()

    def draw_Electrode(self):
        source = vtk.vtkCylinderSource()
        source.SetCenter(0, 0, 0)
        source.SetRadius(20)
        source.SetResolution(100)
        source.SetHeight(10)

        trans = vtk.vtkTransform()
        trans.PostMultiply()
        trans.RotateX(90)
        trans.RotateY(0)
        trans.Translate(0, 0, 0)

        trans_filter = vtk.vtkTransformPolyDataFilter()
        trans_filter.SetInputConnection(source.GetOutputPort())
        trans_filter.SetTransform(trans)

        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(trans_filter.GetOutputPort())

        actor = vtk.vtkActor()
        actor.SetMapper(mapper)
        actor.GetProperty().SetColor(1, 1, 1)
        actor.GetProperty().SetOpacity(0.5)

        self.ren.AddActor(actor)

        poly_data = trans_filter.GetOutput()
        nbcells = poly_data.GetNumberOfCells()
        cells = []
        for i in range(nbcells):
            cells.append(poly_data.GetCell(i))

        normalsCalc = vtk.vtkPolyDataNormals()

        normalsCalc.SetInputData(poly_data)
        normalsCalc.ComputePointNormalsOn()
        normalsCalc.ComputeCellNormalsOff()
        # normalsCalc.SetSplitting(0)
        # normalsCalc.FlipNormalsOff()
        # normalsCalc.ConsistencyOn()
        # normalsCalc.AutoOrientNormalsOn()
        normalsCalc.Update()

        arrowSource = vtk.vtkArrowSource()

        glyph3D = vtk.vtkGlyph3D()
        glyph3D.SetInputData(normalsCalc.GetOutput())
        glyph3D.SetSourceConnection(arrowSource.GetOutputPort())
        glyph3D.OrientOn()
        glyph3D.SetVectorModeToUseNormal()
        glyph3D.SetScaleFactor(200)
        glyph3D.Update()

        mapper2 = vtk.vtkPolyDataMapper()
        mapper2.SetInputConnection(glyph3D.GetOutputPort())

        actor2 = vtk.vtkActor()
        actor2.SetMapper(mapper2)
        actor2.GetProperty().SetColor(1, 1, 1)

        self.ren.AddActor(actor2)
        self.set_center()
        self.Render()



def main():
    import sys
    app = QApplication(sys.argv)


    ex = Cylinder(app)
    ex.setWindowTitle('Cylinder')
    # ex.showMaximized()
    ex.show()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()

如果您使用此 example 中的字形配置并将比例因子设置为 1.0,它会起作用。

在此处查看您修改后的函数 draw_Electrode():

def draw_Electrode(self):
    source = vtk.vtkCylinderSource()
    source.SetCenter(0, 0, 0)
    source.SetRadius(20)
    source.SetResolution(100)
    source.SetHeight(10)

    trans = vtk.vtkTransform()
    trans.PostMultiply()
    trans.RotateX(90)
    trans.RotateY(0)
    trans.Translate(0, 0, 0)

    trans_filter = vtk.vtkTransformPolyDataFilter()
    trans_filter.SetInputConnection(source.GetOutputPort())
    trans_filter.SetTransform(trans)

    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputConnection(trans_filter.GetOutputPort())

    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    actor.GetProperty().SetColor(1, 1, 1)
    actor.GetProperty().SetOpacity(0.5)

    self.ren.AddActor(actor)

    normals = vtk.vtkPolyDataNormals()
    normals.SetInputConnection(trans_filter.GetOutputPort())

    arrow= vtk.vtkArrowSource()

    glyph = vtk.vtkGlyph3D()
    glyph.SetInputConnection(normals.GetOutputPort())
    glyph.SetSourceConnection(arrow.GetOutputPort())
    glyph.SetVectorModeToUseNormal()
    glyph.SetScaleModeToScaleByVector()
    glyph.SetScaleFactor(1)

    mapper2 = vtk.vtkPolyDataMapper()
    mapper2.SetInputConnection(glyph.GetOutputPort())

    actor2 = vtk.vtkActor()
    actor2.SetMapper(mapper2)
    actor2.GetProperty().SetColor(1, 0, 0)

    self.ren.AddActor(actor2)
    self.set_center()
    self.Render()