现已完成三维地形图三角网的三维显示和用多线程计算平基土石方功能,正在准备进入将用于计算出的全部三棱柱(锥)实体也能以三维方式显示出来,并可以选中三维实体和查看他们的属性,现将如何在已知几个点的情况下画出任意的多面体的示例代码发出来,供大家参考,我只提供了一个三角形类和一个三棱锥类的vtk示例画法,其他任意面的多面体实体按三棱锥的画法一样,就不一一举例了。
示例代码运行效果如下图
python">import sys
import sys,numpy,time,copy,random
import numpy as np
from math import *import PyQt5
from PyQt5 import *
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtGui import QColor
import vtkmodules.all as vtk
from vtkmodules.all import vtkConeSource, vtkPolyDataMapper, vtkActor,vtkRenderer, vtkRenderWindow, vtkRenderWindowInteractor, vtkPolyDataMapper, vtkPoints, vtkVertexGlyphFilter
from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkFiltersSources import vtkRegularPolygonSource
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleImage
from vtkmodules.vtkCommonDataModel import vtkCellArray
from vtkmodules.vtkRenderingCore import (vtkActor,vtkPolyDataMapper,vtkRenderer,vtkRenderWindow,
)#定义vct所有点、线、面、文本、多面体角色的基类
class vtkActors(object):actorsCount=0 #所有角色的总数量def __init__(self,win,ren):super().__init__()self.vtkWidget=win #3D显示窗体self.ren=ren #渲染器self.actor= vtk.vtkActor() #角色变量self.defCol=np.array([255/255,255/255,255/255]) #默认颜色为黑色,rgb为0-1间的小数,即原RGB/255的值self.bUseZcols=True #是否使用Z字义的字典中分配的不同颜色self.bDrawObj=True #是否画本对象(对复杂三维,不在正面显示的,可以设置此值为False,在程序中就不执行重画了,防止程序卡顿)#定义点的属性值self.bDrawPoint=False #是否画出点self.pointR=0.1 #画点球的颜色self.pointCol=self.getVtkCol('red') #画点球的半径#定义线的属性值self.trans=1.0 #默认面域透明值0=透明 1=不透明self.bDrawLine=True #是否画线self.lineWidth=1 #线宽self.lineType=0x0303 #线类型self.lineCol=self.getVtkCol('forestgreen') #线颜色#定义面的属性值 self.bDrawPlane=True #是否画面self.planeCol=self.getVtkCol('darkgreen') #面的颜色#定义文本的属性值self.bDrawText=True #是否文本self.txtCol=self.getVtkCol('white') #画文本颜色self.drawType=0 #画文本类型:0=vtk模式, 1=图像图式self.bFace=True #画文本是否总正面对观察者self.fontName='宋体'self.fontSize=9self.bUnderline=Falseself.bBold=Falseself.bItalic=False#将颜色文本字符转为vtk的颜色值def getVtkCol(self,colStr):col=QColor(colStr)colR=col.red()/255colG=col.green()/255colB=col.blue()/255return np.array([colR,colG,colB])#定义一个三角形面的类:所有实体的面均由三角形面构成
class Actor_triangle(vtkActors):actorsCount=0 #所有角色的总数量def __init__(self,win,ren,point1,point2,point3,trans=1,lineCol='forestgreen',planeCol='darkgreen',txtCol='lightseagreen'):super().__init__(win,ren) #基类vctActors初始化self.trans=trans #默认面域透明值0=透明 1=不透明self.points=np.array([point1,point2,point3])self.lineCol=self.getVtkCol(lineCol)self.planeCol=self.getVtkCol(planeCol)self.txtCol=self.getVtkCol(txtCol)self.drawTrangle()def drawTrangle(self): if(self.bDrawObj):# 创建一个三角形面points = vtk.vtkPoints()points.InsertNextPoint(self.points[0][0], self.points[0][1], self.points[0][2])points.InsertNextPoint(self.points[1][0], self.points[1][1], self.points[1][2])points.InsertNextPoint(self.points[2][0], self.points[2][1], self.points[2][2])triangle = vtk.vtkCellArray()triangle.InsertNextCell(3)triangle.InsertCellPoint(0)triangle.InsertCellPoint(1)triangle.InsertCellPoint(2)polydata_plane = vtk.vtkPolyData()polydata_plane.SetPoints(points)polydata_plane.SetPolys(triangle)# 过滤器用于生成三角形triangleFilter = vtk.vtkTriangleFilter()triangleFilter.SetInputData(polydata_plane)triangleFilter.Update()#三角形三条边线if(self.bDrawLine):line_actor = vtk.vtkActor() #角色:可分别设置,但为改颜色等应定义为类全局变量cells = vtk.vtkCellArray()polydata_line = vtk.vtkPolyData()pointIdStart = points.InsertNextPoint(self.points[0]) pointIdEnd = points.InsertNextPoint(self.points[1])singleLineCell = [pointIdStart,pointIdEnd]cells.InsertNextCell(2,singleLineCell)pointIdStart = points.InsertNextPoint(self.points[1]) pointIdEnd = points.InsertNextPoint(self.points[2])singleLineCell = [pointIdStart,pointIdEnd]cells.InsertNextCell(2,singleLineCell)pointIdStart = points.InsertNextPoint(self.points[0]) pointIdEnd = points.InsertNextPoint(self.points[2])singleLineCell = [pointIdStart,pointIdEnd]cells.InsertNextCell(2,singleLineCell)polydata_line.SetLines(cells)polydata_line.SetPoints(points)mapper_line = vtk.vtkPolyDataMapper() #网络线渲染器:应分别设置mapper_line.SetInputData(polydata_line)line_actor.SetMapper(mapper_line)# 获取actor的属性并设置线宽和线型property = line_actor.GetProperty()property.SetColor(self.lineCol) #设置画线的颜色,字串改成0-1的RGB颜色property.SetLineWidth(1) # 设置线宽property.SetLineStipplePattern(0x0303) # 设置线型:实线= 0x0000 虚线1=0x0101 虚线2=0x0303 点划线1=0x0505 点划线2=0x0909#property.SetLineStippleRepeatFactor(1) # 设置线型的重复因子 self.ren.AddActor(line_actor) #画三角形的面if(self.bDrawPlane):# 创建映射器mapper = vtk.vtkPolyDataMapper()mapper.SetInputConnection(triangleFilter.GetOutputPort())# 创建Actorself.actor.SetMapper(mapper)self.actor.GetProperty().SetColor(self.planeCol) # 设置面的颜色,字串改成对应的0-1的RGBself.actor.GetProperty().SetOpacity(self.trans) # 设置不透明度# 将Actor添加到渲染器self.ren.AddActor(self.actor)self.vtkWidget.GetRenderWindow().Render()#更改颜色后重画三角形 def reDraw(self,bDrawLine=True,trans=1,lineCol='forestgreen',planeCol='darkgreen',txtCol='lightseagreen'):#self.ren.RemoveAllViewProps() #清除所有角色#self.ren.RemoveActor() #清除本角色self.bDrawLine=bDrawLineself.trans=transself.lineCol=self.getVtkCol(lineCol)self.planeCol=self.getVtkCol(planeCol)self.txtCol=self.getVtkCol(txtCol)self.drawTrangle()#定义三棱锥角色类,每个三棱锥由四个点四个面构构成的实体
class Actor_3Pyramid(vtkActors):actorsCount=0 #所有角色的总数量def __init__(self,win,ren,p1,p2,p3,p0,trans=1,lineCol='forestgreen',planeCol='darkgreen',txtCol='lightseagreen'):super().__init__(win,ren) #基类vctActors初始化self.trans=trans #默认面域透明值0=透明 1=不透明self.points=np.array([p1,p2,p3,p0])self.lineColtxt=lineColself.planeColtxt=planeColself.txtColtxt=txtColself.draw3Pyramid()def draw3Pyramid(self):if(self.bDrawObj):self.triange1=Actor_triangle(self.vtkWidget,self.ren,self.points[0],self.points[1],self.points[3],self.trans,self.lineColtxt,self.planeColtxt,self.txtColtxt)self.triange2=Actor_triangle(self.vtkWidget,self.ren,self.points[0],self.points[2],self.points[3],self.trans,self.lineColtxt,self.planeColtxt,self.txtColtxt) self.triange3=Actor_triangle(self.vtkWidget,self.ren,self.points[0],self.points[1],self.points[2],self.trans,self.lineColtxt,self.planeColtxt,self.txtColtxt) self.triange4=Actor_triangle(self.vtkWidget,self.ren,self.points[1],self.points[2],self.points[3],self.trans,self.lineColtxt,self.planeColtxt,self.txtColtxt) #只更改颜色等属性重画三棱锥def reDraw3Pyramid(self,bDrawLine=True,trans=1,lineCol='forestgreen',planeCol='darkgreen',txtCol='lightseagreen'): self.trans=trans #默认面域区透明值0=透明 1=不透明self.bDrawLine=bDrawLine #是否画出边线self.lineColtxt=lineColself.planeColtxt=planeColself.txtColtxt=txtColself.draw3Pyramid()###########################################################################
#定义三棱柱角色类:每个三棱柱由6个点5个三角表面构成,同三棱锥画法相同,不提供代码
class Actor_3Prism(vtkActors):actorsCount=0 #所有角色的总数量def __init__(self,win,ren):super().__init__(win,ren) #基类vctActors初始化###########################################################################class MyWindow(QMainWindow):def __init__(self):super().__init__()self.initUI()self.setWindowTitle('Python+QT5+vtk画多面体示例')def initUI(self):# 创建VTK渲染窗口交互器self.vtkWidget = QVTKRenderWindowInteractor()self.setCentralWidget(self.vtkWidget)self.show()# 创建VTK渲染器#在基类vtkActors中定义#2.创建各种初始化的角色self.actor = vtk.vtkActor()#3.vtk渲染器(将执行单元和背景组合在一起按照某个视角绘制)self.ren = vtk.vtkRenderer()self.ren.SetBackground(0, 0, 0)self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()point1=np.array([0,0,0])point2=np.array([3,0,0])point3=np.array([0,5,0])point0=np.array([4,4,4])#vtk3= Actor_triangle(self.vtkWidget,self.ren,point1,point2,point3)vtk4=Actor_3Pyramid(self.vtkWidget,self.ren,point1,point2,point3,point0)#vtk4.reDraw3Pyramid(False,1,'red','red')
if __name__ == '__main__':app = QApplication(sys.argv)window = MyWindow()app.exec_()