python+vtk+qt实现三维文件的基本读取显示上色边界边
python代码
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
import vtkmodules.all as vtk
from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class Ui_MainWindow(QMainWindow):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
# =======================
self.vtk_show = QVTKRenderWindowInteractor(self.widget)
self.vtk_show.resize(self.widget.size())
self.sphere = None;
self.mapper = None;
self.actor = None;
self.edgeActor = None;
self.renderer = None;
self.i_ren = None;
self.filename = "";
self.colorbg = (1.0, 1.0, 1.0);
self.color3d = (1.0, 1.0, 1.0);
self.coloreg = (1.0, 0, 0);
self.pushButton_off.clicked.connect(self.read_off)
self.pushButton_obj.clicked.connect(self.read_obj)
self.pushButton_ply.clicked.connect(self.read_ply)
self.pushButton_stl.clicked.connect(self.read_stl)
self.pushButton_vtk.clicked.connect(self.read_vtk)
self.pushButton_e.clicked.connect(self.show_edge)
self.pushButton_bg.clicked.connect(self.change_bg)
self.pushButton_3d.clicked.connect(self.change_3d)
self.pushButton_ec.clicked.connect(self.change_edge)
# =======================
def read_off(self):
self.read_file("off")
if self.filename!="":
self.off2obj()
self.sphere = vtk.vtkOBJReader()
self.sphere.SetFileName("./1.obj")
self.sphere.Update()
self.show()
def read_obj(self):
self.read_file("obj")
if self.filename != "":
self.sphere = vtk.vtkOBJReader()
self.sphere.SetFileName(self.filename)
self.sphere.Update()
self.show()
def read_ply(self):
self.read_file("ply")
if self.filename != "":
self.sphere = vtk.vtkPLYReader()
self.sphere.SetFileName(self.filename)
self.sphere.Update()
self.show()
def read_stl(self):
self.read_file("stl")
if self.filename != "":
self.sphere = vtk.vtkSTLReader()
self.sphere.SetFileName(self.filename)
self.sphere.Update()
self.show()
def read_vtk(self):
self.read_file("vtk")
if self.filename != "":
self.sphere = vtk.vtkPolyDataReader()
self.sphere.SetFileName(self.filename)
self.sphere.Update()
self.show()
def show_edge(self):
if self.renderer!=None:
_translate = QtCore.QCoreApplication.translate
if self.edgeActor==None:
self.pushButton_e.setText(_translate("MainWindow", "关闭边界边"))
featureEdges = vtk.vtkFeatureEdges()
featureEdges.SetInputConnection(self.sphere.GetOutputPort())
featureEdges.BoundaryEdgesOn()
featureEdges.FeatureEdgesOff()
featureEdges.ManifoldEdgesOff()
featureEdges.NonManifoldEdgesOff()
featureEdges.ColoringOff()
featureEdges.Update()
edgeMapper = vtk.vtkPolyDataMapper()
edgeMapper.SetInputConnection(featureEdges.GetOutputPort())
self.edgeActor = vtk.vtkActor()
self.edgeActor.SetMapper(edgeMapper)
self.edgeActor.GetProperty().SetColor(self.coloreg)
self.renderer.AddActor(self.edgeActor)
else:
self.pushButton_e.setText(_translate("MainWindow", "打开边界边"))
self.renderer.RemoveActor(self.edgeActor)
self.edgeActor = None
def change_edge(self):
if self.edgeActor != None :
color = QColorDialog.getColor()
if color.isValid():
self.edgeActor.GetMapper().ScalarVisibilityOff()
self.coloreg = color.getRgb()[0:3]
color_list = list(self.coloreg)
color_list[0] = float(color_list[0] / 255)
color_list[1] = float(color_list[1] / 255)
color_list[2] = float(color_list[2] / 255)
self.coloreg = tuple(color_list)
self.edgeActor.GetProperty().SetColor(self.coloreg)
def change_bg(self):
color = QColorDialog.getColor()
if color.isValid():
self.colorbg = color.getRgb()[0:3]
color_list = list(self.colorbg)
color_list[0] = float(color_list[0] / 255)
color_list[1] = float(color_list[1] / 255)
color_list[2] = float(color_list[2] / 255)
self.colorbg = tuple(color_list)
self.renderer.SetBackground(self.colorbg)
def change_3d(self):
color = QColorDialog.getColor()
if color.isValid():
self.actor.GetMapper().ScalarVisibilityOff()
self.color3d = color.getRgb()[0:3]
color_list = list(self.color3d)
color_list[0] = float(color_list[0] / 255)
color_list[1] = float(color_list[1] / 255)
color_list[2] = float(color_list[2] / 255)
self.color3d = tuple(color_list)
self.actor.GetProperty().SetColor(self.color3d)
def show(self):
# 2.polyDataMapper
self.mapper = vtk.vtkPolyDataMapper()
self.mapper.SetInputConnection(self.sphere.GetOutputPort())
self.mapper.Update()
# 3.actor
self.actor = vtk.vtkActor()
self.actor.SetMapper(self.mapper)
self.actor.GetProperty().SetColor(self.color3d)
# 4.renderer
self.renderer = vtk.vtkRenderer()
self.renderer.AddActor(self.actor)
self.renderer.SetBackground(self.colorbg)
# 5.windows
self.vtk_show.GetRenderWindow().AddRenderer(self.renderer)
self.i_ren = self.vtk_show.GetRenderWindow().GetInteractor()
self.vtk_show.Render()
self.i_ren.Initialize()
self.vtk_show.Start()
def read_file(self,file_type):
dialog = QFileDialog()
dialog.setFileMode(QFileDialog.ExistingFile)
dialog.setAcceptMode(QFileDialog.AcceptOpen)
self.filename, _ = dialog.getOpenFileName(dialog, "Open file", "", "files (*." + file_type + ")")
self.label.setText(self.filename)
def off2obj(self):
with open(self.filename, "r") as f:
lines = f.readlines()
v_num = 10
outputlines = list()
for i in range(0, len(lines)):
lines[i] = lines[i].rstrip('\n')
# 获取定点数和面数
if i == 1:
line = lines[i].split(" ")
v_num = int(line[0])
# 定点数据生成
if i > 1 and i < (v_num + 2):
s = "v " + lines[i] + "\n"
outputlines.append(s)
# 面数据生成
if i > (v_num + 1):
ss = lines[i].split(" ")
news = ""
if ss[0] != "":
for j in range(1, int(ss[0]) + 1):
ss[j] = str(int(ss[j]) + 1)
news += " " + ss[j]
s = "f " + news + "\n"
outputlines.append(s)
fw = open("./1.obj", "w")
fw.writelines(outputlines)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
ui文件转py文件命令
pyuic5 -o main.ui main.py
python打包exe命令
pyinstaller -F -w -i main.ico main.py # 打包成单文件程序
pyinstaller -w -i main.ico main.py # 打包成多文件程序
效果: