如何在带有 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()
我正在尝试显示圆柱源每个单元格的法线 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()