Python教程

Qt for Python——基于PySide6实现CFD网格文件可视化(一)

本文主要是介绍Qt for Python——基于PySide6实现CFD网格文件可视化(一),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、基于Qt Data Visualization Examples中的Surface Example模块(未完成)

Surface Example - Qt for Python 给出了一种通过Q3DSurface绘制三维空间曲面的例子,包含以下几个功能:

  • 建立QSurfaceDataProxy并设置数据
  • 使用QHeightMapSurfaceDataProxy来显示三维高度图
  • 有三种不同研究图的选项
  • 坐标轴的范围用于显示图形的选定部分
  • 改变主题 
  • 设置自定义表面梯度

 绘制三维空间内曲面的例子

这个例子与CFD软件中网格显示十分相似,在此基础上也许可以实现对.msh文件、.su2文件的显示。

 

首先,在main.py中,我们创建一个QApplication,实例化Q3DSurface,并为它创建一个窗口容器:

app = QApplication([])
graph = Q3DSurface()
container = QWidget.createWindowContainer(graph)

 

调用createWindowContainer是必需的,因为所有的数据可视化图形类(Q3DBars, Q3DScatter和Q3DSurface)继承QWindow。任何继承QWindow的类都不能以任何其他方式作为小部件使用。

然后我们将创建水平和垂直布局,将图表添加到容器中,将垂直布局添加到水平布局:

widget = QWidget()
hLayout = QHBoxLayout(widget)
vLayout = QVBoxLayout()
hLayout.addWidget(container, 1)
hLayout.addLayout(vLayout)
vLayout.setAlignment(Qt.AlignTop)

main.py中的其余代码是为Q3DSurface中的特性创建控件小部件。我们已经分离了将这些特性转换为surfacegraph.py的代码,只将小部件的信号连接到surfacegraph.py中的函数中。下一章解释更多关于使用Q3DSurface的方法。

 

设置代理(Proxies)和数据

首先,我们实例化一个新的QSurfaceDataProxy,并将其附加到一个新的QSurface3DSeries上:

m_sqrtSinProxy = QSurfaceDataProxy()
m_sqrtSinSeries = QSurface3DSeries(m_sqrtSinProxy)

 

然后我们用一个简单的平方根和正弦波数据填充代理。这是通过创建一个新的QSurfaceDataArray实例并向其添加QSurfaceDataRow元素来完成的。创建的QSurfaceDataArray被设置为QSurfaceDataProxy的数据阵列。

def fillSqrtSinProxy(self):

    stepX = (sampleMax - sampleMin) / float(sampleCountX - 1)
    stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1)
    dataArray = QSurfaceDataArray()
    dataArray.reserve(sampleCountZ)
    for i in range(0, sampleCountZ ):
        newRow = QSurfaceDataRow(sampleCountX)
        # Keep values within range bounds, since just adding step can cause minor drift due
        # to the rounding errors.
        z = qMin(sampleMax, (i * stepZ + sampleMin))
        index = 0
        for j in range(0, sampleCountX):
            x = qMin(sampleMax, (j * stepX + sampleMin))
            R = qSqrt(z * z + x * x) + 0.01f
            y = (qSin(R) / R + 0.24f) * 1.61f
            (newRow)[index++].setPosition(QVector3D(x, y, z))

        dataArray << newRow

    m_sqrtSinProxy.resetArray(dataArray)

 接下来就可以在这个模块上进行修改,将平方根和正弦波数据更改为.msh中的网格点数据。

 

之前曾写过一个简陋的.msh文件读取二维网格点的代码,但是用Qchart显示不出来,可能是因为读取效率低或者QChart本身效率低:

path = 'Mesh/fluent.msh'
lo = open(path, 'r+')
lines = lo.readlines()
x = []
y = []
for line in lines:
    t = line.split()
    # 以空格为分割进行划分
    if len(t) == 2 and t[0] != '(2':
        x.append(float(t[0]))
        y.append(float(t[1]))

 天真的想把这部分代码耦合到上面的Surface Example中,发现上面画网格的方式是:x轴坐标不变,y、z坐标变化,进而形成一个平行于y-z轴所在平面的曲线,所以在不进行较大修改的前提下不可以画出不规则网格。

虽然没有成功,但是之后可以继续研究,PySide中QtDataVisualization模块还是很强大的。

 

二、基于Matplotlib Widget 3D Example范例

Matplotlib Widget 3D Example - Qt for Python给出了基于Matplotlib与PuSide6的面显示模块代码。

 

 

 

 我注意到Triangular Surface中的数据形式与CFD网格数据十分相似,三角形不规则网格划分。

 

def plot_triangular_surface(self):
    # Data
    radii = np.linspace(0.125, 1.0, 8)
    angles = np.linspace(0, 2 * np.pi, 36, endpoint=False)[..., np.newaxis]
    self.X = np.append(0, (radii * np.cos(angles)).flatten())
    self.Y = np.append(0, (radii * np.sin(angles)).flatten())
    self.Z = np.sin(-self.X * self.Y)

    self.set_canvas_table_configuration(len(self.X), (self.X, self.Y, self.Z))
    self._ax.plot_trisurf(self.X, self.Y, self.Z, linewidth=0.2, antialiased=True)
    self.canvas.draw()

上面代码给出了绘制三角形网格组成曲面的代码,对这个稍加修改之后可以对.msh文件进行可视化,网格点数达到10000时速度也不是很慢,同时也可以实现拖拽、缩放、旋转等操作。

 

 

 上面是修改完成后绘制.msh文件的效果,虽然界面还比较简陋,但是已经具备基本功能了。

这篇关于Qt for Python——基于PySide6实现CFD网格文件可视化(一)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!