现已完成三维地形图三角网的三维显示和用多线程计算平基土石方功能,正在准备进入将用于计算出的全部三棱柱(锥)实体也能以三维方式显示出来,并可以选中三维实体和查看他们的属性(类似于其他三维软件的选择功能,不知道能实现不)
现将用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