Merge remote-tracking branch 'refs/remotes/lamp/LAMPCAE-dev-wuxiaxin' into LAMPCAE-dev

pull/1/head
剑古敛锋 2024-07-10 16:34:27 +08:00
commit 5bcc3cf68d
3 changed files with 530 additions and 0 deletions

View File

@ -0,0 +1,213 @@
//
// Created by wuxiaxin on 24-7-9.
//
// You may need to build the project (run Qt uic code generator) to get "ui_wavemodel.h" resolved
#include "wavemodel.h"
#include "ui_wavemodel.h"
#include "MainWindow/MainWindow.h"
#include "Settings/BusAPI.h"
#include "Settings/GraphOption.h"
#include "Common/DebugLogger.h"
#include <QSettings>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkStructuredGrid.h>
#include <vtkPoints.h>
#include <vtkFloatArray.h>
#include <vtkPointData.h>
#include <QVBoxLayout>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <qDebug>
#include <vtkSTLWriter.h>
#include <QMessageBox>
#include <QFileInfo>
#include <QFileDialog>
namespace wave {
wavemodel::wavemodel(GUI::MainWindow* _mainwindow, QWidget* parent)
: QDialog(_mainwindow),
_mainwindow(_mainwindow),
ui(new Ui::wavemodel)
{
ui->setupUi(this);
connect(ui->ShowWave_pushButton, &QPushButton::clicked, this, &wavemodel::on_push_wave_models_slot);
connect(ui->SaveModel_pushButton, &QPushButton::clicked, this, &wavemodel::on_push_save_models_slot);
initVTKView();
// Display default grid
vtkSmartPointer<vtkStructuredGrid> grid = createDefaultGrid();
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
mapper->SetInputData(grid);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
_render->AddActor(actor);
_render->ResetCamera();
_renderWindow->Render();
}
wavemodel::~wavemodel()
{
delete ui;
}
void wavemodel::initVTKView() {
// 添加控件
_qvtkWidget = new QVTKOpenGLNativeWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout(ui->modelViewContent);
mainLayout->addWidget(_qvtkWidget);
// 初始化渲染器
_renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
_qvtkWidget->setRenderWindow(_renderWindow);
_render = vtkSmartPointer<vtkOpenGLRenderer>::New();
_render->SetGradientBackground(true);
// 设置渲染背景色
Setting::GraphOption *option = Setting::BusAPI::instance()->getGraphOption();
QColor topcolor = option->getBackgroundTopColor();
QColor bottomcolor = option->getBackgroundBottomColor();
_render->SetBackground2(topcolor.redF(), topcolor.greenF(), topcolor.blueF());
_render->SetBackground(bottomcolor.redF(), bottomcolor.greenF(), bottomcolor.blueF());
// 开启硬件加速特性
_render->UseDepthPeelingOn();
_render->SetUseFXAA(true);
_interactor = _renderWindow->GetInteractor();
_renderWindow->AddRenderer(_render);
}
vtkSmartPointer<vtkStructuredGrid> wavemodel::createDefaultGrid()
{
vtkSmartPointer<vtkStructuredGrid> structuredGrid = vtkSmartPointer<vtkStructuredGrid>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkFloatArray> heights = vtkSmartPointer<vtkFloatArray>::New();
heights->SetName("Height");
int gridSize = 10; // Default grid size
double spacing = 1.0; // Grid spacing
for (int i = 0; i < gridSize; ++i) {
for (int j = 0; j < gridSize; ++j) {
double x = i * spacing;
double y = j * spacing;
double z = sin(i) * cos(j); // Sample height value
points->InsertNextPoint(x, y, z);
heights->InsertNextValue(z);
}
}
structuredGrid->SetDimensions(gridSize, gridSize, 1);
structuredGrid->SetPoints(points);
structuredGrid->GetPointData()->SetScalars(heights);
return structuredGrid;
}
void wavemodel::on_push_wave_models_slot() {
//清除所有模型
_render->RemoveAllViewProps();
// 获取 textEdit_t 和 textEdit_v 的输入值
QString text_t = ui->textEdit_t->toPlainText();
QString text_v = ui->textEdit_v->toPlainText();
QString text_r = ui->textEdit_r->toPlainText();
QString text_g = ui->textEdit_g->toPlainText();
_structuredGrid= vtkSmartPointer<vtkStructuredGrid>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkFloatArray> heights = vtkSmartPointer<vtkFloatArray>::New();
heights->SetName("Height");
double t = text_t.toDouble();
double v = text_v.toDouble();
double rand = text_r.toDouble();
double grid = text_g.toDouble();
const double g = 9.8; // 重力加速度常数
const int m = 5; // theta 的段数
const int n = 5; // omg 的段数
const double T = 12.5; // 平均波浪周期
// const int grid_size = 101; // x 和 y 的大小为 101 (1500/15 + 1)
// 其他参数
double omg_0 = 2 * M_PI / T;
double min_omg = 0.3;
double max_omg = 0.8;
double d_omg = (max_omg - min_omg) / n;
double d_theta = M_PI / m;
double z = 0.0;
for (int xi = 0; xi < grid; ++xi) {
for(int yi = 0; yi < grid; ++yi) {
points->InsertNextPoint(15.0 * xi, 15.0 * yi, 0.0);
heights->InsertNextValue(0);
}
}
double temp,omg_i,k_i,theta_j,eps,S_omg,p,q,fi_u;
// 计算波浪高度
for (int i = 1; i <= n; ++i) {
double omg_i = (rand + i - 1) * d_omg + min_omg;
double k_i = omg_i * omg_i / g;
for (int j = 1; j <= m; ++j) {
theta_j = -M_PI / 2 + d_theta * j;
eps = M_PI / 2 * (rand);
S_omg = 6.65e-4 * g * g * std::exp(-0.35 * g /std::pow( (v * omg_i), 4)) / std::pow(omg_i, 5);
p = 0.5 + 0.82 * std::exp(-0.5 * std::pow(omg_i / omg_0, 4));
q = 0.32 * std::exp(-0.5 * std::pow(omg_i / omg_0, 4));
fi_u = 1 / M_PI * (1 + p * std::cos(2 * theta_j) + q * std::cos(4 * theta_j));
for(int pid=0;pid<points->GetNumberOfPoints();pid++){
double* ppoint=points->GetPoint(pid);
temp = k_i * 15*ppoint[0] * std::cos(theta_j) + k_i * 15*ppoint[1] * std::sin(theta_j) - omg_i * t + eps;
ppoint[2] = std::cos(temp) * std::sqrt(2 * S_omg * fi_u * d_omg * d_theta) + ppoint[2];
points->SetPoint(pid,ppoint[0],ppoint[1],ppoint[2]);
heights->SetValue(pid,ppoint[2]);
}
}
}
double range[2];
heights->GetRange(range);
double minvalue = range[0];
double maxvalue = range[1];
qDebug()<<"Minimum value: " << minvalue;
qDebug()<<"Maximum value: " << maxvalue;
_structuredGrid->SetDimensions(grid, grid, 1);
_structuredGrid->SetPoints(points);
_structuredGrid->GetPointData()->SetScalars(heights);
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
mapper->SetInputData(_structuredGrid);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
_render->AddActor(actor);
_render->ResetCamera();
//更新渲染窗口
_renderWindow->Render();
_qvtkWidget->update();
}
} // namespace wave

View File

@ -0,0 +1,61 @@
//
// Created by wuxiaxin on 24-7-9.
//
#ifndef LAMPCAE_WAVEMODEL_H
#define LAMPCAE_WAVEMODEL_H
#include <QDialog>
#include "ModuleBase/graph3DWindow.h"
#include <QString>
#include "QVTKOpenGLNativeWidget.h"
#include <QMap>
#include <QStringList>
#include <QListWidget>
#include <QWidget>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkStructuredGrid.h>
namespace GUI {
class MainWindow;
}
namespace wave {
QT_BEGIN_NAMESPACE
namespace Ui {
class wavemodel;
}
QT_END_NAMESPACE
class wavemodel : public QDialog {
Q_OBJECT
public:
explicit wavemodel(GUI::MainWindow* _mainwindow, QWidget* parent = nullptr);
~wavemodel() override;
public slots:
void on_push_wave_models_slot();
void on_push_save_models_slot();
private:
GUI::MainWindow* _mainwindow;
Ui::wavemodel* ui;
QVTKOpenGLNativeWidget* _qvtkWidget;
vtkSmartPointer<vtkRenderer> _render;
vtkSmartPointer<vtkGenericOpenGLRenderWindow> _renderWindow;
vtkSmartPointer<vtkRenderWindowInteractor> _interactor;
void initVTKView();
vtkSmartPointer<vtkStructuredGrid> createDefaultGrid();
};
} // namespace wave
#endif // LAMPCAE_WAVEMODEL_H

View File

@ -0,0 +1,256 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>wave::wavemodel</class>
<widget class="QWidget" name="wave::wavemodel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>994</width>
<height>839</height>
</rect>
</property>
<property name="windowTitle">
<string>wavemodel</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="minimumSize">
<size>
<width>350</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLabel" name="label_t">
<property name="geometry">
<rect>
<x>10</x>
<y>100</y>
<width>100</width>
<height>16</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16</height>
</size>
</property>
<property name="text">
<string>请输入时间t(s)</string>
</property>
</widget>
<widget class="QLabel" name="label_v">
<property name="geometry">
<rect>
<x>10</x>
<y>190</y>
<width>100</width>
<height>16</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16</height>
</size>
</property>
<property name="text">
<string>请输入速度v(m/s)</string>
</property>
</widget>
<widget class="QPushButton" name="ShowWave_pushButton">
<property name="geometry">
<rect>
<x>0</x>
<y>510</y>
<width>310</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>确定</string>
</property>
</widget>
<widget class="QTextEdit" name="textEdit_t">
<property name="geometry">
<rect>
<x>120</x>
<y>90</y>
<width>141</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QTextEdit" name="textEdit_v">
<property name="geometry">
<rect>
<x>120</x>
<y>180</y>
<width>141</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_r">
<property name="geometry">
<rect>
<x>10</x>
<y>280</y>
<width>100</width>
<height>16</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16</height>
</size>
</property>
<property name="text">
<string>请输入随机数种子(0-1)</string>
</property>
</widget>
<widget class="QTextEdit" name="textEdit_r">
<property name="geometry">
<rect>
<x>120</x>
<y>270</y>
<width>141</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_g">
<property name="geometry">
<rect>
<x>10</x>
<y>370</y>
<width>100</width>
<height>16</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16</height>
</size>
</property>
<property name="text">
<string>请输入网格大小:</string>
</property>
</widget>
<widget class="QTextEdit" name="textEdit_g">
<property name="geometry">
<rect>
<x>120</x>
<y>360</y>
<width>141</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="SaveModel_pushButton">
<property name="geometry">
<rect>
<x>0</x>
<y>610</y>
<width>310</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>保存模型stl文件</string>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QWidget" name="modelViewContent" native="true">
<property name="minimumSize">
<size>
<width>600</width>
<height>600</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>1000</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>