三维地形图计算软件(六)-用PYQT5+vtk画点云及三维文本

在上一篇文章的基础上,增加了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)
    #根据一个四边形平面分解成两个三角形(因要计算距离,传入的是坐标值,返回的是
### 关于Qt和PCL用于点三维模型软件开发 #### 使用集成开发环境进行项目搭建 为了构建基于Qt和PCL(point cloud library)的应用程序,建议采用配置良好的集成开发环境来简化项目的创建过程[^1]。 #### 示例代码展示如何加载并显示点数据 下面是一个简单的Python脚本例子,它展示了怎样利用PyQt5以及VTK库配合PCL来进行基本的点处理与可视化操作: ```python import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget import vtk from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor import pcl class PointCloudViewer(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): layout = QVBoxLayout() # 创建QVTK窗口部件作为渲染区域 self.vtkWidget = QVTKRenderWindowInteractor(self) layout.addWidget(self.vtkWidget) container = QWidget() container.setLayout(layout) self.setCentralWidget(container) ren = vtk.vtkRenderer() # 渲染器对象 self.vtkWidget.GetRenderWindow().AddRenderer(ren) iren = self.vtkWidget.GetRenderWindow().GetInteractor() # 加载点文件 (这里假设有一个.pcd格式的点文件) p = pcl.load_XYZRGB('path_to_your_point_cloud_file.pcd') points = vtk.vtkPoints() vertices = vtk.vtkCellArray() for i in range(p.size): pt = p[i] id_ = points.InsertNextPoint(pt[0], pt[1], pt[2]) vertices.InsertNextCell(1) vertices.InsertCellPoint(id_) point = vtk.vtkPolyData() point.SetPoints(points) point.SetVerts(vertices) mapper = vtk.vtkPolyDataMapper() if vtk.VTK_MAJOR_VERSION <= 5: mapper.SetInput(point) else: mapper.SetInputData(point) actor = vtk.vtkActor() actor.SetMapper(mapper) ren.AddActor(actor) style = vtk.vtkInteractorStyleTrackballCamera() iren.SetInteractorStyle(style) self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = PointCloudViewer() sys.exit(app.exec_()) ``` 此段代码实现了通过PyQt5 GUI框架结合VTK图形库实现对PCD格式点文件的读取、转换为VTK兼容的数据结构,并最终呈现在界面上的功能[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mr_LuoWei2009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值