在上一篇文章的基础上,增加了Actor_txts类,用于在VTK三维视中画出文本(文本可设置成总是正面对着屏幕显示,也可以设置成跟随VTK视旋转时旋转),但一直没有能够正确显示汉字,查了些资料,也一直没有成功,有这方面经验的老师可否对此类的显示汉字方法进行改进并能提供给我,将非常感谢。
示例代码显示了1000个随机点,并为每个点作了文本标记(点序号)
主窗口PYQT5代码如下:
#测试自定义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):
#内部函数:创建指定数量的点云
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中定义使用,此定义变量在本示例没有使用
#4、画1000个点示例
pointNum=1000
points=createRandPointsCloud(pointNum,0,10,0,10,0,10)
vtkPoints=Actor_points(self.vtkWidget,self.render,points,1,0.05,True,1,'white','green') #画点半径为0.01,点为球体,颜色为绿色
#6、为每一个点标注序号文本(文本对VTK显示影响最大,文本越多,运行越卡)
actTxt=Actor_txts(self.vtkWidget,self.render)
for id in range(pointNum):
actTxt.appendtextData(points[id][0],points[id][1],points[id][2],str(id),1.0,0,0,0.05,0.05,0.05,'宋体',9,False,False,False)
actTxt.drawVtk3DText(bOneActor=True,bFace=False,bImgDraw=False,DPI=360)
vtkPoints.update_render() #如在在类中没有主动调用刷新,界面未出现时,此处刷新一次显示视图
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
app.exec()
增加了Actor_txts类的VTK点线面实体的角色类完整代码如下:
# -*- coding: utf-8 -*-
#QtVtkActors.py:基于vtk的各种三维实体对象类(点,线、面、四面体、三棱柱等)
#类 QtVtkActors:所有vtk三维角色的基类
#类 Actor_points:三维点类
#类 Actor_lines:三维画线类
#类 Actor_txts:三维画文本类
#类 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 #多面体的体积
#设置角色绘制的场景
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)
#根据一个四边形平面分解成两个三角形(因要计算距离,传入的是坐标值,返回的是