用PySide6的界面结合vtk库自定义了一套绘制三维图形用的基本元素的类
基类:QtVtkActors
子类 Actor_points: 三维点类
子类 Actor_lines: 三维画线类
子类 Actor_triangle: 三维三角形面域类
子类 Actor_3Pyramid: 三维三棱锥类(四面体)类
子类 Actor_3Prism: 三维三棱柱类(五面体)类
子类 Actor_4Pyramid: 三维四棱锥类
所定义的类只是按常规面向对象的类定义方式进行的编码,没有采用多线程和缓冲等技术,只作为一个学习用示例代码,当存在大量的点线面和实体对象要进行绘制时,可能会因使用了太多的角色对象造成内存被大量占用和绘制三维时出现卡顿的现象,用于小型三维对象的创建和显示应没有问题。
示例代码运行效果如下图(绘制一1000个点、1000个文本(对点标号),一条直线、一个三角形、一个四面体、一个三棱柱、一个四棱锥)
测试主窗体mainwindow.py代码如下:
#测试自定义vtk点线面类的QT主窗体模块mainWindow.py
import sys,numpy,time,copy,random
import numpy as np
from math import *import PySide6
from PySide6 import *
from PySide6 import QtWidgets, QtCore,QtGui
from PySide6.QtWidgets import *
from PySide6.QtCore import *
#from PySide6.QtGui import *
from PySide6.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.setWindowTitle('Python+PySide6+vtk画点云、文本、线、三角形面、四面体、三棱柱、四棱锥')self.resize(1024,768)self.testDrawVtkObj() def testDrawVtkObj(self):#内部函数:创建指定数量的点云def createRandPointsCloud(count,xmin=-1.0,xmax=1.0,ymin=-1.0,ymax=1.0,zmin=-1.0,zmax=1.0,bUseZcol=True):self.bUseZcols=bUseZcolx=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#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中定义使用,此定义变量在本示例没有使用#---------------------------------------------1、在VTK中绘制点云及文本--------------------------------------------------#画1000个点示例pointNum=1000pointR=0.05 #所绘点云采用球型时的球半径 offsetR=1.1*pointR #所绘点云对应点号文本偏points=createRandPointsCloud(pointNum,0,30,0,30,0,30)vtkPoints=Actor_points(self.vtkWidget,self.render,points,1,pointR,True,1,'white','green') #画点半径为0.01,点为球体,颜色为绿色#为每一个点标注序号文本(文本对VTK显示影响最大,文本越多,运行越卡)actTxt=Actor_txts(self.vtkWidget,self.render)for id in range(pointNum):actTxt.appendtextData(points[id][0]+offsetR,points[id][1]+offsetR,points[id][2]+offsetR,str(id),1.0,0,0,0.05,0.05,0.05,'宋体',9,False,False,False)actTxt.drawVtk3DText(bOneActor=True,bFace=True,bImgDraw=False,DPI=360)#---------------------------------------------2、在VTK中绘制一条直线示例----------------------------------------lines=np.array([[10,10,10,12,13,14],[12,10,12,17,17,19]]) #要绘制的两条直线的数据,np二维数据,vtkLines=Actor_lines(self.vtkWidget,self.render,lines,0,2,True) #画线宽2实线,颜色为默认灰色#vtkLines.reDraw(1,0x0303,True,'yellow') #测试重画线为1宽虚线,黄色,去除#看效果#---------------------------------------------3、在VTK中绘制三角形面示例----------------------------------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') #重画三角形,黄边蓝面,透明度60%,去除#看效果#---------------------------------------------4、画一三棱锥(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') #重新以蓝线红面重画,去除#看效果#-----------------------------------------5、画一三棱柱(5面体)示例--------------------------------A0=np.array([0,0,10]) #定义三棱柱两个三角形(不一定要求平行)共6个顶点的坐标数据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,'lightseagreen','red') #重新以黄线lightseagreen面重画,去除#看效果#vtk5.reDrawPoly(True,False,1,'yellow','red') #重新以黄线红面重画,不画面,去除#看效果#vtk5.reDrawPoly(True,True,1,'yellow','green') #重新以黄线绿面重画,不画线,去除#看效果#-----------------------------------------6、画一四棱柱(每个四棱柱由5个点5个面6个三角形面构成)示例--------------------------------A0=np.array([7,3,2]) #定义四棱锥一个四边角形面和一个顶点共5个顶点的坐标数据B1=np.array([11,9,10])C2=np.array([13,16,5])D3=np.array([25,2,11])P4=np.array([5,5,9])vtk4Pyramid=Actor_4Pyramid(self.vtkWidget,self.render,A0,B1,C2,D3,P4)#vtk4Pyramid.reDrawPoly(True,True,1,'burlywood','gold') #重新以黄线burlywood色面重画#vtk4Pyramid.reDrawPoly(True,False,1,'blue','red') #重新以蓝线红面重画,不画面,去除#看效果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_txts:三维画文本类
#类 Actor_lines:三维画直线类
#类 Actor_triangle:三维画三角形面域类
#类 Actor_3Pyramid:三维画三棱锥类(四面体)
#类 Actor_3Prism:三维画三棱柱类(五面体)
#类 Actor_4Pyramid:三维画四棱锥类
#类 。。。。。。。
#by luowei 2024
import sys,numpy,time,copy,random
import numpy as np
from math import *
from PySide6 import *
from PySide6 import QtWidgets, QtCore
from PySide6.QtWidgets import *
from PySide6.QtCore import *
#from PySide6.QtGui import *
from PySide6.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=0x0909self.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=9self.bUnderline=Falseself.bBold=Falseself.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 #多面体的体积#设置角色绘制的场景def setVctScene(self,win,ren):self.vtkWidget=win #3D显示窗体self.ren=ren #渲染器#转换字符为UTF8,让VTK支持中文def string_To_UTF8(self,vtkstr): utf8_encoded_string = vtkstr.encode('utf-8')return utf8_encoded_string #将颜色文本字符转为vtk的颜色值def getVtkCol(self,colStr):col=QColor(colStr)colR=col.red()/255colG=col.green()/255colB=col.blue()/255return np.array([colR,colG,colB])#得到两点间的距离def get2PointsDis(self,p1,p2):return sqrt((p2[0]-p1[0])**2+(p2[1]-p1[1])**2+(p2[2]-p1[2])**2)#根据一个四边形平面分解成两个三角形(因要计算距离,传入的是坐标值,返回的是按传入点的序号组成的两个三角形数组)def get1QuadTo2Tri(self,A0,B1,C2,D3,A0id,B1id,C2id,D3id):tri1=[A0id,B1id,C2id] #第一个三角形任意取三个点构成,剩下的一个点有两种构成三角形的可能DAC 或DABLD3A0=self.get2PointsDis(D3,A0)LD3B1=self.get2PointsDis(D3,B1) LD3C2=self.get2PointsDis(D3,C2) tri2=[]if(LD3A0>=LD3B1 and LD3A0>=LD3C2): #D和A点是对角tri2=[D3id,B1id,C2id]elif(LD3B1>=LD3A0 and LD3B1>=LD3C2): #D和B点是对角tri2=[D3id,A0id,C2id]elif(LD3C2>=LD3A0 and LD3C2>=LD3B1): #D和C点是对角tri2=[D3id,A0id,B1id]else:print('四边形分解成两个三角形有例外')return tri1,tri2#根据三棱柱上下两个三角形的6个点,分别分解出三个四边形(未完成)def getQuad4(self,A0,B1,C2,D3,E4,F5,A0id=0,B1id=1,C2id=2,D3id=3,E4id=4,F5id=5):#内部函数,判断两条直线是否在一个平面内def getInOneRegion(p1,p2,p3,p4):return False# 定义两条直线的方程,这里以参数形式的二维向量来表示直线# 例如:直线1的方程为 ax + by + c = 0#????如何得到直线方程??????????????line1 = np.array([a1, b1, c1])line2 = np.array([a2, b2, c2])# 判断两条直线是否共面的条件是它们的向量垂直# 计算向量line1和line2的叉乘cross_product = np.cross(line1, line2)# 如果叉乘结果是零向量,则两直线共面if np.allclose(cross_product, np.zeros(3)):print("两条直线在同一个平面内,即使它们可能不平行。")return Trueelse:print("两条直线不在同一个平面内。")return False#重新刷新显示所有已被加入渲染器的全部角色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=lineColtxtself.regionColtxt=RegionColtxtself.textColtxt=txtColtxtfor 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添加到rendererself.actor_Points.GetProperty().SetColor(self.pointCol) # 设置点为指定颜色self.render.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添加到rendereractor_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添加到rendererself.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添加到rendereractor_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添加到rendererself.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=bUseZcolx=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=bDrawPointreturnelse:self.bDrawPoint=bDrawPoint#对重画点是否需要全部重构进行评估bInit=Falseif(pointType != self.pointType): #所画类型发生变化bInit=Trueself.pointType=pointTypeif(abs(pointR-self.pointR)>0.001): #所画大小发生变化bInit=Trueself.pointR=pointRif(bOneActor!=self.bOneActor): #角色定义方式发生变化bInit=Trueself.bOneActor=bOneActor if(bInit): #全部重新构造点和重新画出点,此时可能会耗时更多self.render.RemoveActor(self.actor_Points) self.pointCol=self.getVtkCol(pointColtxt)self.trans=transself.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=lineTypeself.lineWidth=lineWidthself.bDrawLine=bDrawLineself.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=lineStartlineEnd=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) #重新画线角色#更改线r的属性后重画本批次点 def reDraw(self,lineType=0x0000,lineWidth=1,bDrawLine=True,lineColtxt='lightslategray'): if(not bDrawLine): #不画线,从渲染器中删除本线集角色self.render.RemoveActor(self.actor_Lines) self.bDrawLine=bDrawLinereturnelse:self.bDrawPoint=bDrawLine#对重画线是否需要全部重构进行评估bInit=False #对线都不存在重新构造if(bInit): #全部重新构造线和重新画出线,此时可能会耗时更多self.render.RemoveActor(self.actor_Lines) self.lineType=lineTypeself.lineWidth=lineWidthself.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() #重新刷新绘制本点集角色 #为避免频繁刷新,需参照上下文,决定此处是否保留此代码,防止刷新过于频繁
#定义vtk的文本集合类:未优化,一个文本地应一个actor,主要是想保证每个文本可以有独立的属性有特性,但文本过多时,因同时定义的角色过多,会造成卡顿,后期作优化,同一批次文本属性相同时,只定义一个actor
class Actor_txts(QtVtkActors):actorsCount=0 #所有角色的总数量def __init__(self,win,ren):super().__init__(win,ren) #基类vctActors初始化self.vtkTxtDatas=[] #要绘制的文本集合,非NP结构self.vtkTxtDatas.clear()#增加一个要绘制的文字数据,二维共14列 def appendtextData(self,x,y,z,txt,r=1.0,g=1.0,b=1.0,xcale=0.2,ycale=0.2,zcale=0.2,fontname="宋体",fontsize=9,bold=False,italic=False,undline=False):vctTxtData1=[x,y,z,txt,r,g,b,xcale,ycale,zcale,fontname,fontsize,bold,italic,undline]self.vtkTxtDatas.append(vctTxtData1)#计算合理的文本显示尺寸(根据XY坐标的区间)def getVtkFontSize(self,bImgDraw,minX,maxX,minY,maxY):dxy=max(abs(maxX-minX),abs(maxY-minY))sxyz=dxy/1920*1.0self.txtScale=np.array([sxyz,sxyz,sxyz])if(bImgDraw): #图象模式下self.fontSize=9self.txtScale=np.array([sxyz/self.fontSize,sxyz/self.fontSize,sxyz/self.fontSize])#bOneActor=True,为防止大量的文本actro,采用一个actor来画本批次全部txt,属性一致,减少卡顿#将初始化的self.vtkTxtDatas画在VTK-3D上 bFace=False 文字在旋转时是否总是正面向上 #bImgDraw=False 不采用图象渲染模式,文字显示大小同字号无关,只同XYZ比例有关,当比例值为1时,表示一个字符占用一个空间单位尺寸#bImgDraw=True 采用图象渲染模式,文字显示大小同字号有关,也同XYZ比例有关,清晰度同字号有差。文本最终显示大小=字号*XYZ比例 DPI=图象渲染模式下的清晰度 #一般不用图象模式def drawVtk3DText(self,bOneActor=True,bFace=False,bImgDraw=False,DPI=360):bOneActor=False #对使用一个角色来渲染全部文本没有成功,先不理此函数参数,self.bFace=bFaceself.bImgDraw=bImgDrawif(len(self.vtkTxtDatas)>0):#一个文本用一个actor,每个文本的属性(颜色,字号等)都可不相同,文本太多时可能会造成卡顿if(not bOneActor): for oneText in self.vtkTxtDatas:vtkTxtxYZs=np.array(oneText[0:3],dtype=float) #一维[0.,1.,2.]文本显示的位置坐标,np浮点类型vtkTxt=self.string_To_UTF8(oneText[3]) #要显示的字符串vtkTxtCols=np.array(oneText[4:7],dtype=float) #[1.,1.,1.]文本显示颜色,np浮点类型vtkTxtScales=np.array(oneText[7:10],dtype=float) #[0.2,0.2,0.2]文本显示的三个方向的比例:对非图象模式有用(字号无用)lstTxtFonts=oneText[10:15] #列表一维["宋体"9,True,False,False]不用np,用np所的成员变更将会自动转成字符型,字号在图象模式下有用,XYZ比列无用actor = vtk.vtkFollower()if(not bImgDraw):# 创建一个文本源textSource = vtk.vtkVectorText()textSource.SetText(vtkTxt)# 创建一个文本映射器mapper = vtk.vtkPolyDataMapper()mapper.SetInputConnection(textSource.GetOutputPort()) actTextProperty=actor.GetProperty() # 此属性可更改角色(文本)颜色,不能更改字体actTextProperty.SetColor(vtkTxtCols[0], vtkTxtCols[1],vtkTxtCols[2]) # 设置颜色actor.SetMapper(mapper)actor.AddPosition(vtkTxtxYZs[0],vtkTxtxYZs[1],vtkTxtxYZs[2]+0.0*self.pointR) # 设置文本的在3D中的坐标位置actor.SetScale(vtkTxtScales[0],vtkTxtScales[1],vtkTxtScales[2]) # 设置文本的大小:只同此参数有关,同字体字号无关#将当前完成的角色加入渲染器self.render.AddActor(actor)#文字转为图象再进行渲染模式,以下代码可以显示了,但还是无中文,else:mapper=vtk.vtkDataSetMapper()str2Img=vtk.vtkFreeTypeStringToImage()vtkTextProperty=vtk.vtkTextProperty()imgData=vtk.vtkImageData()#vtkTextProperty.SetFontFamily(4) #VTK_FONT_FILE=4vtkTextProperty.SetFontFamilyToArial() # 设置字体为Arial,,这是一种支持中文的字体 vtkTextProperty.SetFontFile("./res/仿宋.ttf")vtkTextProperty.SetFontSize(lstTxtFonts[1]) # 设置字体大小:字号为1时表示所有字符在三维1单位画出,清晰度将会很差vtkTextProperty.SetBold(lstTxtFonts[2]) # 设置粗体vtkTextProperty.SetItalic(lstTxtFonts[3]) # 设置斜体 vtkTextProperty.SetColor(vtkTxtCols[0], vtkTxtCols[1],vtkTxtCols[2]) str2Img.RenderString(vtkTextProperty,vtkTxt,DPI,imgData) #360dpi的清晰度mapper.SetInputDataObject(imgData)actor.SetMapper(mapper)actor.AddPosition(vtkTxtxYZs[0],vtkTxtxYZs[1],vtkTxtxYZs[2]+0.0*self.pointR) # 设置文本的在3D中的坐标位置actor.SetScale(vtkTxtScales[0],vtkTxtScales[1],vtkTxtScales[2]) # 设置文本的大小的比例:如字号为10,全部文字将画在10个空间单位,再此比例缩放#将当前完成的角色加入渲染器self.render.AddActor(actor)if(self.bFace):#self.render.ResetCameraClippingRange()actor.SetCamera(self.render.GetActiveCamera()) # 文本始终正面显示#本批次全部文本采用一个actor来画,全部文本属性一致,可节约内存和减少卡顿 else: appender = vtk.vtkAppendPolyData()actor = vtk.vtkFollower() #只定义一个角色#单一角色的非图形模式下:不支持???????if(not bImgDraw):for oneText in self.vtkTxtDatas:vtkTxtxYZs=np.array(oneText[0:3],dtype=float) #一维[0.,1.,2.]文本显示的位置坐标,np浮点类型vtkTxt=self.string_To_UTF8(oneText[3]) #要显示的字符串textSource = vtk.vtkVectorText()textSource.SetText(vtkTxt) #textSource.设置文本显示位置??textSource.Update()appender.AddInputData(textSource.GetOutput())appender.Update() # 更新合并操作# 创建一个文本映射器mapper = vtk.vtkPolyDataMapper()mapper.SetInputConnection(textSource.GetOutputPort()) actTextProperty=actor.GetProperty() # 此属性可更改角色(文本)颜色,不能更改字体actTextProperty.SetColor(self.textCol) # 设置颜色actor.SetMapper(mapper)#actor.AddPosition(vtkTxtxYZs[0],vtkTxtxYZs[1],vtkTxtxYZs[2]) # 设置文本的在3D中的坐标位置actor.SetScale(self.txtScale) # 设置文本的大小:只同此参数有关,同字体字号无关#将当前完成的角色加入渲染器self.render.AddActor(actor)# 创建一个新的actor使用合并后的数据self.actor.SetMapper(vtk.vtkPolyDataMapper())self.actor.GetMapper().SetInputData(appender.GetOutput())# 将actor添加到rendererself.actor.GetProperty().SetColor(self.textCol) # 设置点为指定颜色:同一种颜色self.render.AddActor(self.actor) #单一角色的图形模式下else: mapper=vtk.vtkDataSetMapper()str2Img=vtk.vtkFreeTypeStringToImage()vtkTextProperty=vtk.vtkTextProperty()imgData=vtk.vtkImageData()#vtkTextProperty.SetFontFamily(4) #VTK_FONT_FILE=4vtkTextProperty.SetFontFamilyToArial() # 设置字体为Arial,,这是一种支持中文的字体 vtkTextProperty.SetFontFile("./res/仿宋.ttf")vtkTextProperty.SetFontSize(self.fontSize) # 设置字体大小:字号为1时表示所有字符在三维1单位画出,清晰度将会很差vtkTextProperty.SetColor(self.textCol) str2Img.RenderString(vtkTextProperty,vtkTxt,DPI,imgData) #360dpi的清晰度#imgData.设置文本显示位置??#imgData.setimgData.update()appender.AddInputData(imgData)appender.Update() #更新合并操作mapper.SetInputDataObject(imgData)actor.SetMapper(mapper)#actor.AddPosition(vtkTxtxYZs[0],vtkTxtxYZs[1],vtkTxtxYZs[2]) # 设置文本的在3D中的坐标位置actor.SetScale(self.txtScale) # 设置文本的大小的比例:如字号为10,全部文字将画在10个空间单位,再此比例缩放#将当前完成的角色加入渲染器self.render.AddActor(actor)if(self.bFace):actor.SetCamera(self.render.GetActiveCamera()) # 文本始终正面显示 #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#定义一个三角形面的类:所有实体的面均由三角形面构成
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的RGBself.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=Falseif((not self.bDrawLine) and bDrawLine): bInit=Trueif((not self.bDrawRegion) and bDrawRegion):bInit=Trueself.bDrawLine=bDrawLineself.bDrawRegion=bDrawRegionself.trans=transself.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的RGBself.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='indigo',txtColtxt='lightseagreen'):super().__init__(win,ren) #基类vctActors初始化self.bDrawLine=bDrawLineself.trans=trans #默认面域透明值0=透明 1=不透明self.lineColtxt=lineColtxtself.regionColtxt=RegionColtxtself.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='orangered',txtColtxt='lightseagreen'):super().__init__(win,ren) #基类vctActors初始化self.bDrawLine=bDrawLineself.trans=trans #默认面域透明值0=透明 1=不透明self.lineColtxt=lineColtxtself.regionColtxt=RegionColtxtself.textColtxt=txtColtxt#对下数据为本类多面体的重要参数设置, 不同的多面体,设置值是不同的self.polyPointsNum = 6 #多面体顶点数 self.polyRegionNum = 5 #多面体的面数self.triangelNum = 8 #多面体的三角形面数self.points=np.array([A0,B1,C2,D3,E4,F5]) #只能保证传入的6个点,前三个为一顶面,后三个为一底面,需要自动判断三角形(但顶面同底面的传入点暂没有完成自动判断对应关系)#self.pointsID=[[0,1,2],[3,4,5],[0,1,3],[4,1,3],[1,2,4],[5,2,4],[2,0,5],[3,0,5]] #三角形点集构成顺序self.pointsID=[]self.pointsID.append([0,1,2])self.pointsID.append([3,4,5])tri1,tri2=self.get1QuadTo2Tri(A0,B1,D3,E4,0,1,3,4)self.pointsID.append(copy.deepcopy(tri1))self.pointsID.append(copy.deepcopy(tri2))tri1,tri2=self.get1QuadTo2Tri(B1,C2,E4,F5,1,2,4,5)self.pointsID.append(copy.deepcopy(tri1))self.pointsID.append(copy.deepcopy(tri2))tri1,tri2=self.get1QuadTo2Tri(C2,A0,F5,D3,2,0,5,3)self.pointsID.append(copy.deepcopy(tri1))self.pointsID.append(copy.deepcopy(tri2))print(self.pointsID)self.initPoly()#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#定义四棱柱角色类:每个四棱柱由5个点5个面6个三角形面构成
class Actor_4Pyramid(QtVtkActors):actorsCount=0 #所有角色的总数量def __init__(self,win,ren,A0,B1,C2,D3,P4,bDrawLine=True,trans=1,lineColtxt='forestgreen',RegionColtxt='gold',txtColtxt='lightseagreen'):super().__init__(win,ren) #基类vctActors初始化self.bDrawLine=bDrawLineself.trans=trans #默认面域透明值0=透明 1=不透明self.lineColtxt=lineColtxtself.regionColtxt=RegionColtxtself.textColtxt=txtColtxt#对下数据为本类多面体的重要参数设置, 不同的多面体,设置值是不同的self.polyPointsNum = 5 #多面体顶点数 self.polyRegionNum = 5 #多面体的面数self.triangelNum = 6 #多面体的三角形面数self.points=np.array([A0,B1,C2,D3,P4]) #只能保证传入的6个点,前三个为一顶面,后三个为一底面,需要自动判断三角形(但顶面同底面的传入点暂没有完成自动判断对应关系)#self.pointsID=[[0,1,2],[0,2,3],[4,0,1],[4,1,2],[4,2,3],[4,0,3]] #三角形点集构成顺序self.pointsID=[]self.pointsID.append([4,0,1])self.pointsID.append([4,1,2])self.pointsID.append([4,2,3])self.pointsID.append([4,0,3])tri1,tri2=self.get1QuadTo2Tri(A0,B1,C2,D3,0,1,2,3)self.pointsID.append(copy.deepcopy(tri1))self.pointsID.append(copy.deepcopy(tri2))print(self.pointsID) self.initPoly()