当前位置: 首页 > news >正文

pyside6学习专栏(十):在PySide6中使用vtk模块绘制点、文本、线、三角形面、四面体、三棱柱、四棱锥等三维的基本元素对象

用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=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
        #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=1000
        pointR=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=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                #多面体的体积
    #设置角色绘制的场景
    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()/255
        colG=col.green()/255
        colB=col.blue()/255
        return 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 或DAB
        LD3A0=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 True
            else:
                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=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.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添加到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) 

    #重新画线角色
    #更改线r的属性后重画本批次点    
    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()                        #重新刷新绘制本点集角色        #为避免频繁刷新,需参照上下文,决定此处是否保留此代码,防止刷新过于频繁
#定义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.0
        self.txtScale=np.array([sxyz,sxyz,sxyz])
        if(bImgDraw):  #图象模式下
            self.fontSize=9
            self.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=bFace
        self.bImgDraw=bImgDraw
        if(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=4
                        vtkTextProperty.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添加到renderer
                    self.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=4
                    vtkTextProperty.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.set
                    imgData.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的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='indigo',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='orangered',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])   #只能保证传入的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=bDrawLine
        self.trans=trans             #默认面域透明值0=透明 1=不透明
        self.lineColtxt=lineColtxt
        self.regionColtxt=RegionColtxt
        self.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()     
   

相关文章:

  • 多线程-线程本地变量ThreadLocal
  • Avalonia 中文乱码
  • C 语言数据结构(一):时/空间复制度
  • java环境部署
  • git修改本地用户名和邮箱和凭据
  • 171. Excel 表列序号
  • C++24--右值引用C++11新特性
  • 前端基础之组件自定义事件
  • Web服务器配置
  • PX4中的DroneCAN的实现库Libuavcan及基础功能示例
  • 利用行波展开法测量横观各向同性生物组织的生物力学特性|文献速递-医学影像人工智能进展
  • Web3 的未来:去中心化如何重塑互联网
  • 美颜SDK架构揭秘:人脸美型API的底层实现与优化策略
  • DeepSeek+Graphrag检索增强
  • 【0010】Python流程控制结构-分支结构详解
  • [machine learning] MACS、MACs、FLOPS、FLOPs
  • 第三章 指令系统
  • K8s控制器Deployment详解
  • 小程序是否支持SSE
  • 《量子潮涌下,DataWorks中AI模型训练框架的变革征途》
  • 为何选择上海?两家外企提到营商环境、人才资源……
  • 著名植物学家、园艺学家,国际植物园协会原主席贺善安逝世
  • 气候多米诺:厄尔尼诺与东南亚跨境害虫或威胁中国粮食安全
  • 伊美第四轮核问题谈判开始
  • 上海发布首份直播电商行业自律公约,禁止虚假宣传、商业诋毁
  • 上海“世行对标改革”的税务样本:设立全国首个税务审判庭、制定首个税务行政复议简易程序