现已完成三维地形图三角网的三维显示和用多线程计算平基土石方功能,正在准备进入将用于计算出的全部三棱柱(锥)实体也能以三维方式显示出来,并可以选中三维实体和查看他们的属性(类似于其他三维软件的选择功能,不知道能实现不)
现将用vtk画点、线、三角形、任意多面体的类代码发出来(画三维文本子类本次没有提供示例代码,下次单独提供),供大家参考使用于各种三维绘图场景,对多面体,我只提供了一个三棱锥和三棱柱的vtk示例画法,其他任意面的多面体实体按三棱锥的画法一样,就不一一举例了。
使用vtk类角色实例化对象时,应注意的问题如下:
如果在代码过程中向渲染器中增加了角色,不论增加时此角色是局部变量还是全局变量,都会永久存在vtk渲染器中,刷新显示时,所有在渲染器中的角色都会被显示出来,只有类全局角色self.xxx才容易对此角色进行属性编辑等操作,如更改颜色、删除角色等操作。对局部变量角色(即函数中的临时变量(vtk角色类型),理论上可节约内存)此角色对象加入渲染器后,不会因为是临时变量角色在函数体退出后而自动删除的(临时变量在函数体完成后应会释放对应的角变量占用的内存,但此角色已加入到渲染器中不会被自动删除的),且不是太容易在渲染器中定位找到此角色(临时变量已释放了)和对此角色进行属性设置等操作。具体使用self.xxx 的类全局角色还是局部变量角色加入vtk渲染器中,要根据具体情况决定。总之self.xxx类全局角色好对其进行属性编辑(如更改颜色等),但要额外再占用一定内存,局部角色可节约一定内存,但不便对其进行属性编辑操作等。
示例代码运行效果如下图
测试vtk三维绘图类的主窗口代码mainidow.py代码如下:
#测试自定义vtk点线面类的QT主窗体模块mainWindow.py
import sys,numpy,time,copy,random
import numpy as np
from math import *
import PyQt5
from PyQt5 import *
from PyQt5 import QtWidgets, QtCore,QtGui
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,
)
from QtVtkActors import * #导入自定义vtk三维对象(点、线、面、三棱锥等各种实体类)
###########################################################################
#测试vtk三维对象类主窗口
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.setWindowTitle('Python+QT5+vtk画多面体示例')
def initUI(self):
#1. 创建VTK渲染窗口交互器
self.vtkWidget = QVTKRenderWindowInteractor()
self.setCentralWidget(self.vtkWidget)
self.show()
#2.创建VTK渲染器
self.render = vtk.vtkRenderer()
self.render.SetBackground(0, 0, 0)
self.vtkWidget.GetRenderWindow().AddRenderer(self.render)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
#3.创建各种初始化的角色
self.actor = vtk.vtkActor() #在封装的基类QtVtkActors中定义使用,此定义变量在本示例没有使用
#4、画点示例
points=np.array([[10,10,10],[12,13,14],[12,10,12],[17,17,19]])
vtkPoints=Actor_points(self.vtkWidget,self.render,points,1,0.2) #画点半径为0.5,点为球体,颜色为默认红色
vtkPoints.reDraw(2,0.2,True,0.8,'white','yellow',True) #重画点为正方体,半边长0.5,黄色
#5、画线示例
lines=np.array([[10,10,10,12,13,14],[12,10,12,17,17,19]])
vtkLines=Actor_lines(self.vtkWidget,self.render,lines,0,2,True) #画线宽2实线,颜色为默认灰色
vtkLines.reDraw(1,0x0303,True,'yellow') #重画线为1宽虚线,黄色
#6、画三角形示例
pointA=np.array([12,13,14])
pointB=np.array([12,10,12])
pointC=np.array([17,17,19])
vtkTriangle= Actor_triangle(self.vtkWidget,self.render,pointA,pointB,pointC) #画三角形颜色为默认色
vtkTriangle.reDraw(True,True,0.6,'red','blue') #重画三角形,黄边蓝面
#7、画一三棱锥(4面体)示例
A0=np.array([20,20,30])
B1=np.array([25,25,30])
C2=np.array([30,20,30])
P3=np.array([40,40,50])
vtk4= Actor_3Pyramid(self.vtkWidget,self.render,A0,B1,C2,P3)
vtk4.reDrawPoly(True,False,1,'blue','red') #重新以蓝线红面重画
#8、画一三棱柱(5面体)示例
A0=np.array([0,0,10])
B1=np.array([5,5,10])
C2=np.array([10,0,10])
D3=np.array([0,0,0])
E4=np.array([5,5,0])
F5=np.array([10,0,0])
vtk5=Actor_3Prism(self.vtkWidget,self.render,A0,B1,C2,D3,E4,F5)
vtk5.reDrawPoly(True,True,1,'yellow','red') #重新以黄线红面重画
vtk5.reDrawPoly(True,False,1,'yellow','red') #重新以黄线红面重画,不画面
vtk5.reDrawPoly(True,True,1,'yellow','green') #重新以黄线绿面重画,不画线
vtkPoints.update_render() #如在在类中没有主动调用刷新,界面未出现时,此处刷新一次显示视图
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
app.exec()
VTK各种角色类:点,线,三角形面,任意多边形面(三棱锥,三棱柱等等)类模块QtVtkActors.py代码如下:
# -*- coding: utf-8 -*-
#QtVtkActors.py:基于vtk的各种三维实体对象类(点,线、面、四面体、三棱柱等)
#类 QtVtkActors:所有vtk三维角色的基类
#类 Actor_points:三维点类
#类 Actor_lines:三维画线类
#类 Actor_triangle:三角形面域类
#类 Actor_3Pyramid:三棱锥类(四面体)
#类 Actor_3Prism:三棱柱类(五面体)
#类 。。。。。。。
#by luowei 2024
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,
)
#定义vtk所有点、线、面、文本、多面体角色的基类
class QtVtkActors(object):
actorsCount=0 #所有角色的总数量
def __init__(self,win,render):
super().__init__()
self.vtkWidget=win #3D显示的QT窗体
self.render=render #渲染器
self.defCol=np.array([255/255,255/255,255/255]) #默认颜色为黑色,rgb为0~1间的小数,即原RGB/255的值
self.bUseZcols=True #是否使用Z字义的字典中分配的不同颜色
self.bDrawObj=True #是否画本对象(对复杂三维,不在正面显示的,可以设置此值为False,在程序中就不执行重画了,防止程序卡顿)
self.bSelected=False #本对角是否被选中
#定义点的属性值
#self.points =np.array([....]) #本角色的np数组点集合:在使用处现定义
#self.vtk_points=vtk.vtkPoints() #本角色的vtk点集合,改为局部变量
self.actor_Points= vtk.vtkActor() #点角色变量:用self类全局变量的作用,可以得到角色的属性以修改编辑器等操作,其他同
self.bDrawPoint=False #是否画出点(以球其他类型的方式)
self.bOneActor=True #对画点,每定义一个点类对象时,如点数大于1,画本批次全部点时是采用一个角色(内存点用小)还是为每个点分配一个角色(好控制每个点)
self.pointType=0 #画出点的为类型:0=以球画点 1=以正方体画点 2=。。。
self.pointR=0.1 #点球的半径
self.pointCol=self.getVtkCol('red') #画点球的颜色
self.selPointCol=self.getVtkCol('blue') #点球被选中时颜色
#定义线的属性值
self.actor_Lines= vtk.vtkActor() #线角色变量:用self类全局变量的作用,可以得到角色的属性以修改编辑器等操作,其他同
self.trans=1.0 #默认面域透明值0=透明 1=不透明
self.bDrawLine=True #是否画线
self.lineWidth=1 #线宽
self.lineType=0x0000 #实线= 0x0000 虚线1=0x0101 虚线2=0x0303 点划线1=0x0505 点划线2=0x0909
self.lineCol=self.getVtkCol('forestgreen') #线颜色
self.selLineCol=self.getVtkCol('blue') #线对象被选中时颜色
#定义面的属性值
self.actor_Regions= vtk.vtkActor() #面角色变量:用self类全局变量的作用,可以得到角色的属性以修改编辑器等操作,其他同
self.bDrawRegion=True #是否画面
self.regionCol=self.getVtkCol('darkgreen') #面的颜色
self.selRegionCol=self.getVtkCol('blue') #面被选中的颜色
#定义文本的属性值
self.actor_Texts= vtk.vtkActor() #文本角色变量:用self类全局变量的作用,可以得到角色的属性以修改编辑器等操作,其他同
self.bDrawText=True #是否文本
self.txtCol=self.getVtkCol('white') #画文本颜色
self.drawType=0 #画文本类型:0=vtk模式, 1=图像图式
self.bFace=True #画文本是否总正面对观察者
self.fontName='宋体'
self.fontSize=9
self.bUnderline=False
self.bBold=False
self.bItalic=False
#定义由点线面组合而成的实体属性
self.actor_Poly= vtk.vtkActor() #多面组合体角色变量
self.vtkTriangles=[] #多面体的三角形对象集合
self.polyPointsNum = 0 #多面体顶点数
self.polyRegionNum = 0 #多面体的面数
self.triangelNum = 0 #多面体的三角形面数
self.polyArea=0.0 #多面体的表面积
self.polyVolume=0.0 #多面体的体积
#将颜色文本字符转为vtk的颜色值
def getVtkCol(self,colStr):
col=QColor(colStr)
colR=col.red()/255
colG=col.green()/255
colB=col.blue()/255
return np.array([colR,colG,colB])
#重新刷新显示所有渲染器的已被加入的全部角色
def update_render(self):
self.render.ResetCamera()
self.vtkWidget.GetRenderWindow().Render() #刷新重画
#以三角形面初始化任意多面体(多面体专有属性在子类中定义)
def initPoly(self):
if(self.bDrawObj):
self.vtkTriangles.clear()
for id in range(self.triangelNum):
#print(f'{self.pointsID[id][0]},{self.pointsID[id][1]},{self.pointsID[id][2]}')
onetranglePoints=[self.points[self.pointsID[id][0]],self.points[self.pointsID[id][1]],self.points[self.pointsID[id][2]]]
triangleObj=Actor_triangle(self.vtkWidget,self.render,onetranglePoints[0],onetranglePoints[1],onetranglePoints[2],self.bDrawLine,self.bDrawRegion,self.trans,self.lineColtxt,self.regionColtxt,self.textColtxt)
self.vtkTriangles.append(triangleObj)
#更改颜色等属性重画多面体
def reDrawPoly(self,bDrawLine=True,bDrawRegion=True,trans=1.0,lineColtxt='forestgreen',RegionColtxt='darkgreen',txtColtxt='lightseagreen'):
#self.render.RemoveAllViewProps() #清除所有角色
#self.render.RemoveActor(self.xxxactor) #清除本角色
self.bDrawLine=bDrawLine #是否画出三角形边线
self.bDrawRegion=bDrawRegion
self.trans=trans #默认面域区透明值0=透明 1=不透明
self.lineColtxt=lineColtxt
self.regionColtxt=RegionColtxt
self.textColtxt=txtColtxt
for id in range(self.triangelNum):
self.vtkTriangles[id].reDraw(self.bDrawLine,self.bDrawRegion,self.trans,self.lineColtxt,self.regionColtxt,self.textColtxt)
self.update_render() #重新刷新绘制本实体角色
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#定义画点的类
class Actor_points(QtVtkActors):
actorsCount=0 #所有角色的总数量
def __init__(self,win,ren,points,pointType=1,pointR=0.01,bDrawPoint=True,trans=1,lineColtxt='forestgreen',pointColtxt='red'):
super().__init__(win,ren) #基类vctActors初始化
self.pointType=pointType #画点类型:0=系统默认 1=球,2=正方体 3=....
self.pointR=pointR #画点的球半径或正方体的半边长
self.bDrawPoint=bDrawPoint #是否画出此点
self.trans=trans #默认面域透明值0=透明 1=不透明
self.points=np.array(points) #传入的点可为一个点,也可以为一点集合np(n,3) [[x,y,z],[]]]
self.lineCol=self.getVtkCol(lineColtxt) #保留线颜色属性,对四方体作为点时,是否画出线根据实际情况定
self.pointCol=self.getVtkCol(pointColtxt) #点颜色即为面颜色
self.initVtkPoints() #构造此批次的点角色
#初始化点对象,如果调用此函数前点已被初始化过,删除原已加入vtk的角色,重新按当前属性参数初始化点
#将当前生成的点角色加入渲染器:参数bOneActor=True时表示对每个点均使用一个角色变量,为False时表示本类对象批次只使用一个角色对象
def initVtkPoints(self):
if(self.pointType==0): #标准默认小点
# 创建一个vtkPolyData对象
poly_data = vtk.vtkPolyData()
poly_data.SetPoints(self.vtkPoints)
# 创建一个vtkVertexGlyphFilter对象
glyph_filter = vtk.vtkVertexGlyphFilter()
glyph_filter.SetInputData(poly_data)
glyph_filter.Update()
# 设置点的半径大小
glyph = vtk.vtkSphereSource()
glyph.SetRadius(self.pointR) # 设置点的半径为无效??????????????????
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(glyph_filter.GetOutputPort())
self.actor_Points.SetMapper(mapper)
# 将actor添加到renderer
self.actor_Points.GetProperty().SetColor(self.pointCol) # 设置点为指定颜色
self.ren.AddActor(self.actor_Points)
elif(self.pointType==1): #点全为球体,每个球用了一个actor,角色太多时,可能会造成卡顿
if(not self.bOneActor):
for point in self.points:
sphere_source = vtk.vtkSphereSource() #设置点类型为球
sphere_source.SetRadius(self.pointR) #设置球体半径
mapper = vtk.vtkPolyDataMapper()
actor_pan = vtk.vtkActor() #面角色:必须重新定义,一个点一个actor,不能用全局的self.actor,否则不显示
sphere_source.SetCenter(point[0],point[1],point[2]) #设置球体中心
sphere_source.Update()
mapper.SetInputConnection(sphere_source.GetOutputPort())
actor_pan.SetMapper(mapper)
# 将actor添加到renderer
actor_pan.GetProperty().SetColor(self.pointCol) # 设置点为指定颜色:同一种颜色
self.render.AddActor(actor_pan)
else: #采用一个actor来画本批次的全部球体类型点
appender = vtk.vtkAppendPolyData()
for point in self.points:
sphere_source = vtk.vtkSphereSource() #设置点类型为球
sphere_source.SetRadius(self.pointR) #设置球体半径
sphere_source.SetCenter(point[0],point[1],point[2]) #设置球体中心
mapper = vtk.vtkPolyDataMapper()
sphere_source.Update()
mapper.SetInputConnection(sphere_source.GetOutputPort())
#actors_datas.append(sphere_source.GetOutput())
appender.AddInputData(sphere_source.GetOutput())
appender.Update() # 更新合并操作
# 创建一个新的actor使用合并后的数据
self.actor_Points.SetMapper(vtk.vtkPolyDataMapper())
self.actor_Points.GetMapper().SetInputData(appender.GetOutput())
# 将actor添加到renderer
self.actor_Points.GetProperty().SetColor(self.pointCol) # 设置点为指定颜色:同一种颜色
self.render.AddActor(self.actor_Points)
elif(self.pointType==2): #点全为立方体
if(not self.bOneActor):
for point in self.points:
cube_source = vtk.vtkCubeSource() #设置点类型为立方体
cube_source.SetXLength(2*self.pointR) #设置立方体边长 self.pointR为半边长
cube_source.SetYLength(2*self.pointR)
cube_source.SetZLength(2*self.pointR)
mapper = vtk.vtkPolyDataMapper()
actor_pan = vtk.vtkActor() #面角色:必须重新定义
cube_source.SetCenter(point[0],point[1],point[2]) #设置球体中心
cube_source.Update()
mapper.SetInputConnection(cube_source.GetOutputPort())
actor_pan.SetMapper(mapper)
# 将actor添加到renderer
actor_pan.GetProperty().SetColor(self.pointCol) # 设置点为指定颜色
self.render.AddActor(actor_pan)
else: #采用一个actor来画本批次的全部球体类型点
appender = vtk.vtkAppendPolyData()
for point in self.points:
cube_source = vtk.vtkCubeSource() #设置点类型为立方体
cube_source.SetXLength(2*self.pointR) #设置立方体边长
cube_source.SetYLength(2*self.pointR)
cube_source.SetZLength(2*self.pointR)
mapper = vtk.vtkPolyDataMapper()
cube_source.SetCenter(point[0],point[1],point[2]) #设置立方体中心
cube_source.Update()
mapper.SetInputConnection(cube_source.GetOutputPort())
#actors_datas.append(sphere_source.GetOutput())
appender.AddInputData(cube_source.GetOutput())
appender.Update() # 更新合并操作
# 创建一个新的actor使用合并后的数据
self.actor_Points.SetMapper(vtk.vtkPolyDataMapper())
self.actor_Points.GetMapper().SetInputData(appender.GetOutput())
# 将actor添加到renderer
self.actor_Points.GetProperty().SetColor(self.pointCol) # 设置点为指定颜色:同一种颜色
self.render.AddActor(self.actor_Points)
#在指定三维尺寸空间内创建随机的点云()
def createRandPointsCloud(self,count,xmin=-1.0,xmax=1.0,ymin=-1.0,ymax=1.0,zmin=-1.0,zmax=1.0,bUseZcol=True):
self.bUseZcols=bUseZcol
x=np.random.uniform(xmin,xmax,count)
y=np.random.uniform(ymin,ymax,count)
z=np.random.uniform(zmin,zmax,count)
points = np.stack([x, y, z], axis=-1)
return points
#更改点的属性后重画本批次点
def reDraw(self,pointType=1,pointR=0.01,bDrawPoint=True,trans=1,lineColtxt='forestgreen',pointColtxt='red',bOneActor=True):
if(not bDrawPoint): #不画出点,从渲染器中删除本点集角色
self.render.RemoveActor(self.actor_Points)
self.bDrawPoint=bDrawPoint
return
else:
self.bDrawPoint=bDrawPoint
#对重画点是否需要全部重构进行评估
bInit=False
if(pointType != self.pointType): #所画类型发生变化
bInit=True
self.pointType=pointType
if(abs(pointR-self.pointR)>0.001): #所画大小发生变化
bInit=True
self.pointR=pointR
if(bOneActor!=self.bOneActor): #角色定义方式发生变化
bInit=True
self.bOneActor=bOneActor
if(bInit): #全部重新构造点和重新画出点,此时可能会耗时更多
self.render.RemoveActor(self.actor_Points)
self.pointCol=self.getVtkCol(pointColtxt)
self.trans=trans
self.lineCol=self.getVtkCol(lineColtxt) #暂没有用处
self.initVtkPoints()
else: #只是颜色和透明度发生了变化,无需重构点,以节约运行时间
self.pointCol=self.getVtkCol(pointColtxt)
self.actor_Points.GetProperty().SetColor(self.pointCol)
self.actor_Points.GetProperty().SetOpacity(self.trans)
if(self.pointType==1 or self.pointType==2):
self.update_render() #重新刷新绘制本点集角色 #为避免频繁刷新,需参照上下文,决定此处是否保留此代码,防止刷新过于频繁
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#定义vtk点线集合类:线集对象可能只有一条线,也可能是有多条线(所有线共用颜色,线型等属性)
class Actor_lines(QtVtkActors):
actorsCount=0 #所有线角色的总数量
def __init__(self,win,ren,lines,lineType=0x000,lineWidth=1,bDrawLine=True,lineColtxt='lightslategray'):
super().__init__(win,ren) #基类vctActors初始化
self.lines=np.array(lines) #传入的线集格式[[x1,y1,z1,x2,y2,z2],[...]]
self.lineType=lineType
self.lineWidth=lineWidth
self.bDrawLine=bDrawLine
self.lineCol=self.getVtkCol(lineColtxt)
self.initVtkLines()
#画线集角色(每个类实例化对象可画一根线,也可画一组线,每个角色画线的颜色和线型是一致的)
def initVtkLines(self):
#再画竖直方向的网格平行线
if(len(self.lines)>0):
points = vtk.vtkPoints()
cells = vtk.vtkCellArray()
polydata = vtk.vtkPolyData()
mapper_line = vtk.vtkPolyDataMapper() #网络线渲染器:应分别设置
tmpPoint=np.array([0,0,0])
for xyzPoint in self.lines: #循环画出本批次全部直线,[x1,y1,z1,x2,y2,z2]
lineStart=xyzPoint[0:3] #起点的三个坐标
tmpPoint=lineStart
lineEnd=xyzPoint[3:6] #终点的三个坐标
pointIdStart = points.InsertNextPoint(lineStart)
pointIdEnd = points.InsertNextPoint(lineEnd)
singleLineCell = [pointIdStart,pointIdEnd]
cells.InsertNextCell(2,singleLineCell)
polydata.SetLines(cells)
polydata.SetPoints(points)
mapper_line.SetInputData(polydata)
self.actor_Lines = vtk.vtkActor() #角色:可分别设置,但为改颜色等应定义为类全局变量
self.actor_Lines.SetMapper(mapper_line)
# 获取actor的属性并设置线宽和线型
property = self.actor_Lines.GetProperty()
property.SetColor(self.lineCol) # 设置水平方向画线的颜色
property.SetLineWidth(self.lineWidth) # 设置线宽
property.SetLineStipplePattern(self.lineType) # 设置线型:实线= 0x0000 虚线1=0x0101 虚线2=0x0303 点划线1=0x0505 点划线2=0x0909
#property.SetLineStippleRepeatFactor(1) # 设置线型的重复因子
self.render.AddActor(self.actor_Lines)
#重新画线角色
#更改点的属性后重画本批次点
def reDraw(self,lineType=0x0000,lineWidth=1,bDrawLine=True,lineColtxt='lightslategray'):
if(not bDrawLine): #不画线,从渲染器中删除本线集角色
self.render.RemoveActor(self.actor_Lines)
self.bDrawLine=bDrawLine
return
else:
self.bDrawPoint=bDrawLine
#对重画点是否需要全部重构进行评估
bInit=False #对线都不存在重新构造
if(bInit): #全部重新构造线和重新画出线,此时可能会耗时更多
self.render.RemoveActor(self.actor_Lines)
self.lineType=lineType
self.lineWidth=lineWidth
self.lineCol=self.getVtkCol(lineColtxt)
self.initVtkLines()
else:
property = self.actor_Lines.GetProperty()
property.SetColor(self.lineCol) # 设置画线的颜色
property.SetLineWidth(self.lineWidth) # 设置线宽
property.SetLineStipplePattern(self.lineType) # 设置线型:实线= 0x0000 虚线1=0x0101 虚线2=0x0303 点划线1=0x0505 点划线2=0x090
#self.update_render() #重新刷新绘制本点集角色 #为避免频繁刷新,需参照上下文,决定此处是否保留此代码,防止刷新过于频繁
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#定义一个三角形面的类:所有实体的面均由三角形面构成
class Actor_triangle(QtVtkActors):
actorsCount=0 #所有角色的总数量
def __init__(self,win,ren,point1,point2,point3,bDrawLine=True,bDrawRegion=True,trans=1,lineColtxt='forestgreen',RegionColtxt='darkgreen',txtColtxt='lightseagreen'):
super().__init__(win,ren) #基类vctActors初始化
self.bDrawLine=bDrawLine #三角形是否画出边线
self.bDrawRegion=bDrawRegion #三角形是否画出面
self.trans=trans #默认面域透明值0=透明 1=不透明
self.points=np.array([point1,point2,point3])
self.lineCol=self.getVtkCol(lineColtxt)
self.regionCol=self.getVtkCol(RegionColtxt)
self.txtCol=self.getVtkCol(txtColtxt)
self.initVtkTrangle()
#初始化三角形对象,如果调用此函数前三角形已被初始化过,删除原已加入vtk的角色,重新按当前属性参数初始化三角形
def initVtkTrangle(self):
if(self.bDrawObj):
if(self.actor_Lines.GetLength()>0):
self.render.RemoveActor(self.actor_Lines) #删除之前已加入到vtk渲染器的的线角色,以便按新属新重新初始化角色
if(self.actor_Regions.GetLength()>0):
self.render.RemoveActor(self.actor_Regions) #删除之前已加入到vtk渲染器的的面角色,以便按新属性重新初始化角色
# 创建一个三角形面
vtk_points=vtk.vtkPoints() #本角色的vtk点集合
vtk_points.InsertNextPoint(self.points[0][0], self.points[0][1], self.points[0][2])
vtk_points.InsertNextPoint(self.points[1][0], self.points[1][1], self.points[1][2])
vtk_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_Region = vtk.vtkPolyData()
polydata_Region.SetPoints(vtk_points)
polydata_Region.SetPolys(triangle)
# 过滤器用于生成三角形
triangleFilter = vtk.vtkTriangleFilter()
triangleFilter.SetInputData(polydata_Region)
triangleFilter.Update()
#三角形三条边线
if(self.bDrawLine):
cells = vtk.vtkCellArray()
polydata_line = vtk.vtkPolyData()
pointIdStart = vtk_points.InsertNextPoint(self.points[0])
pointIdEnd = vtk_points.InsertNextPoint(self.points[1])
singleLineCell = [pointIdStart,pointIdEnd]
cells.InsertNextCell(2,singleLineCell)
pointIdStart = vtk_points.InsertNextPoint(self.points[1])
pointIdEnd = vtk_points.InsertNextPoint(self.points[2])
singleLineCell = [pointIdStart,pointIdEnd]
cells.InsertNextCell(2,singleLineCell)
pointIdStart = vtk_points.InsertNextPoint(self.points[0])
pointIdEnd = vtk_points.InsertNextPoint(self.points[2])
singleLineCell = [pointIdStart,pointIdEnd]
cells.InsertNextCell(2,singleLineCell)
polydata_line.SetLines(cells)
polydata_line.SetPoints(vtk_points)
mapper_line = vtk.vtkPolyDataMapper() #网络线渲染器:应分别设置
mapper_line.SetInputData(polydata_line)
self.actor_Lines.SetMapper(mapper_line)
# 获取actor的属性并设置线宽和线型
property = self.actor_Lines.GetProperty()
property.SetColor(self.lineCol) #设置画线的颜色,字串改成0-1的RGB颜色
property.SetLineWidth(1) # 设置线宽
property.SetLineStipplePattern(0x0000) # 设置线型:实线= 0x0000 虚线1=0x0101 虚线2=0x0303 点划线1=0x0505 点划线2=0x0909
#property.SetLineStippleRepeatFactor(1) # 设置线型的重复因子
self.render.AddActor(self.actor_Lines)
#画三角形的面
if(self.bDrawRegion):
# 创建映射器
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(triangleFilter.GetOutputPort())
#设置面的属性值
self.actor_Regions.SetMapper(mapper)
self.actor_Regions.GetProperty().SetColor(self.regionCol) # 设置面的颜色,字串改成对应的0-1的RGB
self.actor_Regions.GetProperty().SetOpacity(self.trans) # 设置透明度
# 将Actor添加到渲染器
self.render.AddActor(self.actor_Regions)
else: #如原先已向vtk中加入了三角形类的角色,应从渲染器中删除,否则会刷新时会被显示出来
self.render.RemoveActor(self.actor_Lines)
self.render.RemoveActor(self.actor_Regions)
#self.update_render() #重新刷新绘制本三角形角色 #为避免频繁刷新,只在多面体中调用一次,三角形类中除非必须外不刷新
#更改颜色后重画三角形
def reDraw(self,bDrawLine=True,bDrawRegion=True,trans=1,lineColtxt='forestgreen',RegionColtxt='darkgreen',txtColtxt='lightseagreen'):
#重画前评估当前是否需要重新构建三角形
bInit=False
if((not self.bDrawLine) and bDrawLine): bInit=True
if((not self.bDrawRegion) and bDrawRegion):bInit=True
self.bDrawLine=bDrawLine
self.bDrawRegion=bDrawRegion
self.trans=trans
self.lineCol=self.getVtkCol(lineColtxt)
self.regionCol=self.getVtkCol(RegionColtxt)
self.txtCol=self.getVtkCol(txtColtxt)
if(bInit): #对原先已被删除了角色的情况,直接调用重新构建
self.initVtkTrangle()
else: #不需要重新构建只需要更改属性即可
#是否画出三角形三条边
if(self.bDrawLine):
if(self.actor_Lines.GetLength()>0): #当前线角色已存在,只是改属性无需删除角色再重新加载角色时,只需改线角色的属性值即可
property = self.actor_Lines.GetProperty()
property.SetColor(self.lineCol) # 设置画线的颜色,字串改成0-1的RGB颜色
property.SetLineWidth(self.lineWidth) # 设置线宽
property.SetLineStipplePattern(self.lineType) # 设置线型:实线= 0x0000 虚线1=0x0101 虚线2=0x0303 点划线1=0x0505 点划线2=0x0909
#property.SetLineStippleRepeatFactor(1) # 设置线型的重复因子
else:
self.render.RemoveActor(self.actor_Lines) #删除之前已加入到vtk渲染器的的线角色,以便按新属新重新初始化角色
#是否画出角形面
if(self.bDrawRegion):
if(self.actor_Regions.GetLength()>0): #当前面角色已存在,只是改属性无需删除角色再重新加载角色时,只需改线角色的属性值即可
self.actor_Regions.GetProperty().SetColor(self.regionCol) # 设置面的颜色,字串改成对应的0-1的RGB
self.actor_Regions.GetProperty().SetOpacity(self.trans) # 设置透明度
else:
self.render.RemoveActor(self.actor_Regions) #删除之前已加入到vtk渲染器的的面角色,以便按新属新重新初始化角色
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#定义三棱锥角色类,每个三棱锥由4个点4个面构4个三角形面构成的实体
class Actor_3Pyramid(QtVtkActors):
actorsCount=0 #本类型实体所有角色的总数量
def __init__(self,win,ren,A0,B1,C2,P3,bDrawLine=True,trans=1,lineColtxt='forestgreen',RegionColtxt='darkgreen',txtColtxt='lightseagreen'):
super().__init__(win,ren) #基类vctActors初始化
self.bDrawLine=bDrawLine
self.trans=trans #默认面域透明值0=透明 1=不透明
self.lineColtxt=lineColtxt
self.regionColtxt=RegionColtxt
self.textColtxt=txtColtxt
#对下数据为本类多面体的重要参数设置, 不同的多面体,设置值是不同的
self.polyPointsNum = 4 #多面体顶点数
self.polyRegionNum = 4 #多面体的面数
self.triangelNum = 4 #多面体的三角形面数
self.points=np.array([A0,B1,C2,P3])
self.pointsID=[[0,1,2],[0,1,3],[0,2,3],[1,2,3]] #三角形点集构成顺序
self.initPoly()
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#定义三棱柱角色类:每个三棱柱由6个点5个面8个三角形面构成,同三棱锥画法相同
class Actor_3Prism(QtVtkActors):
actorsCount=0 #所有角色的总数量
def __init__(self,win,ren,A0,B1,C2,D3,E4,F5,bDrawLine=True,trans=1,lineColtxt='forestgreen',RegionColtxt='darkgreen',txtColtxt='lightseagreen'):
super().__init__(win,ren) #基类vctActors初始化
self.bDrawLine=bDrawLine
self.trans=trans #默认面域透明值0=透明 1=不透明
self.lineColtxt=lineColtxt
self.regionColtxt=RegionColtxt
self.textColtxt=txtColtxt
#对下数据为本类多面体的重要参数设置, 不同的多面体,设置值是不同的
self.polyPointsNum = 6 #多面体顶点数
self.polyRegionNum = 5 #多面体的面数
self.triangelNum = 8 #多面体的三角形面数
self.points=np.array([A0,B1,C2,D3,E4,F5])
self.pointsID=[[0,1,2],[3,4,5],[0,1,4],[0,3,4],[0,3,5],[0,2,5],[1,4,5],[1,2,5]] #三角形点集构成顺序
self.initPoly()