2025-10-27 12:39:49 +00:00
|
|
|
|
#include "ui/Panel/SurfacePanel.h"
|
|
|
|
|
|
#include "ui/DockWidget.h"
|
|
|
|
|
|
#include "ui/DockTitleBar.h"
|
|
|
|
|
|
#include "common/SpdLogger.h"
|
|
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
|
|
#include <QFileInfo>
|
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
|
#include <Q3DCamera>
|
|
|
|
|
|
|
|
|
|
|
|
SurfacePanel::SurfacePanel(int index, const QString& filePath, QWidget* parent)
|
2025-10-27 14:09:22 +00:00
|
|
|
|
: DataPanel(index, FileEntryType::Surface, filePath, parent)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
|
|
|
|
|
m_iMinX = 0; m_iMaxX = 0;
|
|
|
|
|
|
m_iMinY = 0; m_iMaxY = 0;
|
|
|
|
|
|
m_iMinZ = 0; m_iMaxZ = 0;
|
|
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_surfaceContainer = nullptr;
|
|
|
|
|
|
m_surface = nullptr;
|
|
|
|
|
|
m_p3DXAxis = nullptr;
|
|
|
|
|
|
m_p3DYAxis = nullptr;
|
|
|
|
|
|
m_p3DZAxis = nullptr;
|
|
|
|
|
|
m_pSeries = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
m_countX = 0;
|
|
|
|
|
|
m_countY = 0;
|
|
|
|
|
|
m_countZ = 0;
|
|
|
|
|
|
|
2025-11-15 12:47:53 +00:00
|
|
|
|
m_title = "";
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_xTitle = "";
|
|
|
|
|
|
m_yTitle = "";
|
|
|
|
|
|
m_zTitle = "";
|
|
|
|
|
|
|
|
|
|
|
|
m_time = -1.0;
|
|
|
|
|
|
|
|
|
|
|
|
m_thread = nullptr;
|
2025-11-15 12:47:53 +00:00
|
|
|
|
m_mutex = nullptr;
|
2025-11-11 09:44:56 +00:00
|
|
|
|
|
2025-10-27 12:39:49 +00:00
|
|
|
|
LOG_INFO("Created SurfacePanel {} for file: {}", index, filePath.toStdString());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SurfacePanel::SurfacePanel(int index, std::shared_ptr<FileEntrySurface> fileEntry, QWidget* parent)
|
|
|
|
|
|
: DataPanel(index, fileEntry, parent)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_iMinX = 0; m_iMaxX = 0;
|
|
|
|
|
|
m_iMinY = 0; m_iMaxY = 0;
|
|
|
|
|
|
m_iMinZ = 0; m_iMaxZ = 0;
|
|
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_surfaceContainer = nullptr;
|
|
|
|
|
|
m_surface = nullptr;
|
|
|
|
|
|
m_p3DXAxis = nullptr;
|
|
|
|
|
|
m_p3DYAxis = nullptr;
|
|
|
|
|
|
m_p3DZAxis = nullptr;
|
|
|
|
|
|
m_pSeries = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
m_countX = 0;
|
|
|
|
|
|
m_countY = 0;
|
|
|
|
|
|
m_countZ = 0;
|
|
|
|
|
|
|
2025-11-15 12:47:53 +00:00
|
|
|
|
m_title = "";
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_xTitle = "";
|
|
|
|
|
|
m_yTitle = "";
|
|
|
|
|
|
m_zTitle = "";
|
|
|
|
|
|
|
|
|
|
|
|
m_time = -1.0;
|
|
|
|
|
|
|
|
|
|
|
|
m_thread = nullptr;
|
2025-11-15 12:47:53 +00:00
|
|
|
|
m_mutex = nullptr;
|
2025-11-11 09:44:56 +00:00
|
|
|
|
|
2025-10-27 12:39:49 +00:00
|
|
|
|
if (fileEntry) {
|
|
|
|
|
|
LOG_INFO("Created SurfacePanel {} for chart: {}", index, fileEntry->GetName().toStdString());
|
|
|
|
|
|
// Override the title with chart name
|
|
|
|
|
|
title_ = QString("Surface Panel %1 - %2").arg(index).arg(fileEntry->GetName());
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
LOG_WARN("Created SurfacePanel {} with null chart data", index);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SurfacePanel::~SurfacePanel()
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_INFO("Destroyed SurfacePanel {}", GetIndex());
|
2025-11-11 09:44:56 +00:00
|
|
|
|
|
|
|
|
|
|
if (m_pSeries)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_surface->removeSeries(m_pSeries);
|
|
|
|
|
|
m_pSeries->deleteLater();
|
|
|
|
|
|
m_pSeries = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_surface->deleteLater();
|
|
|
|
|
|
m_surface = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_surfaceContainer)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_surfaceContainer->deleteLater();
|
|
|
|
|
|
m_surfaceContainer = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (auto* layout = qobject_cast<QHBoxLayout*>(this->layout()))
|
|
|
|
|
|
{
|
|
|
|
|
|
while (layout->count() > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
QLayoutItem* item = layout->takeAt(0);
|
|
|
|
|
|
if (item)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete item;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_mutex)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete m_mutex;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_thread)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_thread->requestExit();
|
|
|
|
|
|
m_thread->wait();
|
|
|
|
|
|
m_thread->deleteLater();
|
|
|
|
|
|
m_thread = nullptr;
|
|
|
|
|
|
}
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::RefreshPanel()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Implement curve-specific refresh logic here
|
|
|
|
|
|
DataPanel::RefreshPanel();
|
|
|
|
|
|
|
|
|
|
|
|
if (auto fileEntry = fileEntry_->AsSurface()) {
|
|
|
|
|
|
OnDataPanelUpdated(fileEntry);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LOG_INFO("Refreshed TablePanel {}", GetIndex());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::InitUI()
|
|
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
createSurface();
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* mainLayout = new QHBoxLayout(this);
|
|
|
|
|
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
2025-11-11 09:44:56 +00:00
|
|
|
|
mainLayout->addWidget(m_surfaceContainer);
|
2025-10-27 12:39:49 +00:00
|
|
|
|
setLayout(mainLayout);
|
2025-11-11 09:44:56 +00:00
|
|
|
|
|
|
|
|
|
|
m_mutex = new QMutex;
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString SurfacePanel::GetTypeDisplayName() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return "Surface";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::OnDataPanelUpdated(FileEntrySurface* fileEntry)
|
|
|
|
|
|
{
|
2025-11-15 12:47:53 +00:00
|
|
|
|
if (!m_surfaceContainer)
|
|
|
|
|
|
{
|
|
|
|
|
|
createSurface();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-27 12:39:49 +00:00
|
|
|
|
QString strName = fileEntry->GetName();
|
|
|
|
|
|
updateTitle(strName);
|
|
|
|
|
|
|
|
|
|
|
|
FileEntrySurface::ChartProperties propChart = fileEntry->GetChartProperties();
|
|
|
|
|
|
|
|
|
|
|
|
updateTitleAxis(propChart.xTitle, propChart.yTitle, propChart.zTitle);
|
|
|
|
|
|
updateMinMaxX(propChart.xMin, propChart.xMax, propChart.xCount);
|
|
|
|
|
|
updateMinMaxY(propChart.yMin, propChart.yMax, propChart.yCount);
|
|
|
|
|
|
updateMinMaxZ(propChart.zMin, propChart.zMax, propChart.zCount);
|
|
|
|
|
|
|
|
|
|
|
|
QString strFile = fileEntry->GetPath() + "/" + fileEntry->GetFileName();
|
|
|
|
|
|
FileEntrySurface::SurfaceProperties listCurve = fileEntry->GetSurfaceProperties();
|
|
|
|
|
|
updateParseFile(strFile, propChart.timeParam, listCurve);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::OnTimeChanged(double time)
|
|
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_time = time;
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
if (m_surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
QMutexLocker locker(m_mutex);
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
if (m_data.size() > 0)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_pSeries->dataProxy()->resetArray(nullptr);
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
QMap< double, QMap< int, QVector< QVector<QVector3D> > > >::const_iterator ite = m_data.lowerBound(time);
|
|
|
|
|
|
if (ite == m_data.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
ite--;
|
|
|
|
|
|
}
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
QMap< int, QVector< QVector<QVector3D> > > mapData = ite.value();
|
|
|
|
|
|
for (QMap< int, QVector< QVector<QVector3D> > >::Iterator it = mapData.begin(); it != mapData.end(); it++)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
int nIndex = it.key();
|
|
|
|
|
|
QVector< QVector<QVector3D> > listRowData = it.value();
|
|
|
|
|
|
|
|
|
|
|
|
QSurfaceDataArray* data = new QSurfaceDataArray;
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
for (int nI = 0; nI < listRowData.size(); nI++)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
QSurfaceDataRow* dataRow = new QSurfaceDataRow;
|
|
|
|
|
|
|
|
|
|
|
|
QVector<QVector3D> listColData = listRowData[nI];
|
|
|
|
|
|
for (int nJ = 0; nJ < listColData.size(); nJ++)
|
|
|
|
|
|
{
|
|
|
|
|
|
QVector3D v3d = listColData[nJ];
|
|
|
|
|
|
*dataRow << v3d;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*data << dataRow;
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_pSeries->dataProxy()->resetArray(data);
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_surface->setShadowQuality(QAbstract3DGraph::ShadowQuality::ShadowQualityNone);
|
|
|
|
|
|
}
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::updateTitle(const QString & title)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (nullptr != dockWidget_)
|
|
|
|
|
|
{
|
2025-11-15 12:47:53 +00:00
|
|
|
|
m_title = title;
|
|
|
|
|
|
|
2025-10-27 12:39:49 +00:00
|
|
|
|
dockWidget_->setWindowTitle(title);
|
2025-11-11 09:44:56 +00:00
|
|
|
|
|
2025-11-15 12:47:53 +00:00
|
|
|
|
disconnect(dockWidget_, &QDockWidget::visibilityChanged,
|
|
|
|
|
|
this, &SurfacePanel::onVisibilityChanged);
|
|
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
connect(dockWidget_, &QDockWidget::visibilityChanged,
|
|
|
|
|
|
this, &SurfacePanel::onVisibilityChanged);
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::updateTitleAxis(const QString & xTitle, const QString & yTitle, const QString & zTitle)
|
|
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_xTitle = xTitle;
|
|
|
|
|
|
m_yTitle = yTitle;
|
|
|
|
|
|
m_zTitle = zTitle;
|
|
|
|
|
|
|
2025-10-27 12:39:49 +00:00
|
|
|
|
m_p3DXAxis->setTitle(xTitle);
|
|
|
|
|
|
m_p3DXAxis->setTitleVisible(true);
|
|
|
|
|
|
m_p3DYAxis->setTitle(yTitle);
|
|
|
|
|
|
m_p3DYAxis->setTitleVisible(true);
|
|
|
|
|
|
m_p3DZAxis->setTitle(zTitle);
|
|
|
|
|
|
m_p3DZAxis->setTitleVisible(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::updateMinMaxX(float min, float max, int count)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (max > min)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_iMinX = min;
|
|
|
|
|
|
m_iMaxX = max;
|
|
|
|
|
|
|
|
|
|
|
|
if (count > 0)
|
|
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_countX = count;
|
2025-10-27 12:39:49 +00:00
|
|
|
|
m_p3DXAxis->setSegmentCount(count);
|
|
|
|
|
|
}
|
|
|
|
|
|
m_p3DXAxis->setRange(min, max);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::updateMinMaxY(float min, float max, int count)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (max > min)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_iMinY = min;
|
|
|
|
|
|
m_iMaxY = max;
|
|
|
|
|
|
|
|
|
|
|
|
if (count > 0)
|
|
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_countY = count;
|
2025-10-27 12:39:49 +00:00
|
|
|
|
m_p3DYAxis->setSegmentCount(count);
|
|
|
|
|
|
}
|
|
|
|
|
|
m_p3DYAxis->setRange(min, max);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::updateMinMaxZ(float min, float max, int count)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (max > min)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_iMinZ = min;
|
|
|
|
|
|
m_iMaxZ = max;
|
|
|
|
|
|
|
|
|
|
|
|
if (count > 0)
|
|
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_countZ = count;
|
2025-10-27 12:39:49 +00:00
|
|
|
|
m_p3DZAxis->setSegmentCount(count);
|
|
|
|
|
|
}
|
|
|
|
|
|
m_p3DZAxis->setRange(min, max);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::updateParseFile(const QString & strFile, int nT, FileEntrySurface::SurfaceProperties listCurve)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (strFile.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
QMessageBox::information(nullptr, QString::fromLocal8Bit("<EFBFBD><EFBFBD>ʾ"), QString::fromLocal8Bit("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"));
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
{
|
|
|
|
|
|
QMutexLocker locker(m_mutex);
|
|
|
|
|
|
m_data.clear();
|
|
|
|
|
|
m_pSeries->dataProxy()->resetArray(nullptr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int nI = 0; nI < listCurve.size(); nI++)
|
|
|
|
|
|
{
|
|
|
|
|
|
FileEntrySurface::SurfaceProperty surface = listCurve.at(nI);
|
2025-11-02 03:36:10 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_color = surface.color;
|
|
|
|
|
|
|
|
|
|
|
|
QLinearGradient gr;
|
|
|
|
|
|
gr.setColorAt(0.0, surface.color);
|
|
|
|
|
|
gr.setColorAt(0.5, Qt::yellow);
|
|
|
|
|
|
gr.setColorAt(0.8, Qt::red);
|
|
|
|
|
|
gr.setColorAt(1.0, Qt::darkRed);
|
|
|
|
|
|
|
|
|
|
|
|
m_pSeries->setBaseGradient(gr);
|
|
|
|
|
|
m_pSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
|
|
|
|
|
|
//m_pSeries->setSingleHighlightColor(Qt::green);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_thread)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_thread->requestExit();
|
|
|
|
|
|
m_thread->wait();
|
|
|
|
|
|
m_thread->deleteLater();
|
|
|
|
|
|
m_thread = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_thread = new LoadDataThread(this, strFile, nT, listCurve);
|
2025-11-15 12:47:53 +00:00
|
|
|
|
connect(m_thread, &LoadDataThread::signalBeginLoadData,
|
|
|
|
|
|
this, &SurfacePanel::slotBeginLoadData);
|
|
|
|
|
|
connect(m_thread, &LoadDataThread::signalEndLoadData,
|
|
|
|
|
|
this, &SurfacePanel::slotEndLoadData);
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_thread->setMutex(m_mutex);
|
|
|
|
|
|
m_thread->start();
|
|
|
|
|
|
|
|
|
|
|
|
FinalParseFile();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::onVisibilityChanged(bool visible)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (visible)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
if (!m_surfaceContainer)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
createSurface();
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
updateTitleAxis(m_xTitle, m_yTitle, m_zTitle);
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
if (m_iMaxX == m_iMinX)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_p3DXAxis->setAutoAdjustRange(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
updateMinMaxX(m_iMinX, m_iMaxX, m_countX);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_iMaxZ == m_iMinZ)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_p3DZAxis->setAutoAdjustRange(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
updateMinMaxZ(m_iMinZ, m_iMaxZ, m_countZ);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_iMaxY == m_iMinY)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_p3DYAxis->setAutoAdjustRange(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
updateMinMaxY(m_iMaxY, m_iMinY, m_countY);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
QLinearGradient gr;
|
|
|
|
|
|
gr.setColorAt(0.0, m_color);
|
|
|
|
|
|
gr.setColorAt(0.5, Qt::yellow);
|
|
|
|
|
|
gr.setColorAt(0.8, Qt::red);
|
|
|
|
|
|
gr.setColorAt(1.0, Qt::darkRed);
|
|
|
|
|
|
|
|
|
|
|
|
m_pSeries->setBaseGradient(gr);
|
|
|
|
|
|
m_pSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_surface->setHorizontalAspectRatio(1.0);
|
|
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* layout = qobject_cast<QHBoxLayout*>(this->layout());
|
|
|
|
|
|
if (layout)
|
|
|
|
|
|
{
|
|
|
|
|
|
layout->addWidget(m_surfaceContainer);
|
|
|
|
|
|
}
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
if (m_time > -1.0)
|
|
|
|
|
|
{
|
|
|
|
|
|
OnTimeChanged(m_time);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_pSeries)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_surface->removeSeries(m_pSeries);
|
|
|
|
|
|
m_pSeries->deleteLater();
|
|
|
|
|
|
m_pSeries = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_surface)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_surface->deleteLater();
|
|
|
|
|
|
m_surface = nullptr;
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
2025-11-11 09:44:56 +00:00
|
|
|
|
|
|
|
|
|
|
if (m_surfaceContainer)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_surfaceContainer->deleteLater();
|
|
|
|
|
|
m_surfaceContainer = nullptr;
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
2025-11-11 09:44:56 +00:00
|
|
|
|
|
|
|
|
|
|
if (auto* layout = qobject_cast<QHBoxLayout*>(this->layout()))
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
while (layout->count() > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
QLayoutItem* item = layout->takeAt(0);
|
|
|
|
|
|
if (item)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete item;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
2025-11-11 09:44:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::createSurface()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_surface = new Q3DSurface();
|
|
|
|
|
|
m_surface->setFlags(m_surface->flags());
|
|
|
|
|
|
m_surface->setFlipHorizontalGrid(false);
|
|
|
|
|
|
|
|
|
|
|
|
m_p3DXAxis = new QValue3DAxis;
|
|
|
|
|
|
m_p3DXAxis->setSegmentCount(10);
|
|
|
|
|
|
m_p3DXAxis->setRange(-10, 10);
|
|
|
|
|
|
|
|
|
|
|
|
m_p3DYAxis = new QValue3DAxis;
|
|
|
|
|
|
m_p3DYAxis->setSegmentCount(10);
|
|
|
|
|
|
m_p3DYAxis->setRange(-10, 10);
|
|
|
|
|
|
|
|
|
|
|
|
m_p3DZAxis = new QValue3DAxis;
|
|
|
|
|
|
m_p3DZAxis->setSegmentCount(10);
|
|
|
|
|
|
m_p3DZAxis->setRange(-10, 10);
|
|
|
|
|
|
|
|
|
|
|
|
m_surface->setAxisX(m_p3DXAxis);
|
|
|
|
|
|
m_surface->setAxisY(m_p3DYAxis);
|
|
|
|
|
|
m_surface->setAxisZ(m_p3DZAxis);
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
m_surface->activeTheme()->setType(Q3DTheme::Theme(2));
|
|
|
|
|
|
|
|
|
|
|
|
m_pSeries = new QSurface3DSeries;
|
|
|
|
|
|
m_pSeries->setDrawMode(QSurface3DSeries::DrawSurface);
|
|
|
|
|
|
m_surface->addSeries(m_pSeries);
|
|
|
|
|
|
|
|
|
|
|
|
m_surfaceContainer = QWidget::createWindowContainer(m_surface);
|
|
|
|
|
|
m_surfaceContainer->setAutoFillBackground(true);
|
|
|
|
|
|
m_surfaceContainer->setAttribute(Qt::WA_OpaquePaintEvent, true);
|
|
|
|
|
|
m_surfaceContainer->setAttribute(Qt::WA_NoSystemBackground, false);
|
|
|
|
|
|
m_surfaceContainer->setUpdatesEnabled(true);
|
|
|
|
|
|
m_surfaceContainer->setMinimumHeight(100);
|
|
|
|
|
|
|
|
|
|
|
|
m_pSeries->setBaseColor(Qt::green);
|
|
|
|
|
|
m_pSeries->setColorStyle(Q3DTheme::ColorStyleUniform);
|
|
|
|
|
|
m_pSeries->setSingleHighlightColor(Qt::green);
|
|
|
|
|
|
|
|
|
|
|
|
m_pSeries->setMeshSmooth(false);
|
|
|
|
|
|
m_pSeries->setFlatShadingEnabled(false);
|
|
|
|
|
|
|
|
|
|
|
|
m_surface->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPreset(13));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-15 12:47:53 +00:00
|
|
|
|
void SurfacePanel::slotBeginLoadData()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (nullptr != dockWidget_)
|
|
|
|
|
|
{
|
|
|
|
|
|
QString title = m_title + " -- " + QString(tr("Begin LoadData"));
|
|
|
|
|
|
dockWidget_->setWindowTitle(title);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SurfacePanel::slotEndLoadData()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (nullptr != dockWidget_)
|
|
|
|
|
|
{
|
|
|
|
|
|
dockWidget_->setWindowTitle(m_title);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
void SurfacePanel::FinalParseFile()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_iMaxX == m_iMinX)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_p3DXAxis->setAutoAdjustRange(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (m_iMaxZ == m_iMinZ)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_p3DZAxis->setAutoAdjustRange(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (m_iMaxY == m_iMinY)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_p3DYAxis->setAutoAdjustRange(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_surface->setHorizontalAspectRatio(1.0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LoadDataThread::LoadDataThread(SurfacePanel *panel, QString file, int nT, FileEntrySurface::SurfaceProperties listCurve)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_panel = panel;
|
|
|
|
|
|
m_file = file;
|
|
|
|
|
|
m_nT = nT;
|
|
|
|
|
|
m_listCurve = listCurve;
|
|
|
|
|
|
m_exit = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void LoadDataThread::run()
|
|
|
|
|
|
{
|
|
|
|
|
|
QFile file(m_file);
|
|
|
|
|
|
if (file.open(QIODevice::ReadOnly))
|
|
|
|
|
|
{
|
2025-11-15 12:47:53 +00:00
|
|
|
|
emit signalBeginLoadData();
|
|
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
while (!file.atEnd() && !m_exit)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
|
|
|
|
|
QString strLine = file.readLine().simplified();
|
|
|
|
|
|
if (!strLine.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
QStringList listLine = strLine.split(" ");
|
2025-11-11 09:44:56 +00:00
|
|
|
|
double t = listLine.at(m_nT).toDouble();
|
2025-10-27 12:39:49 +00:00
|
|
|
|
|
|
|
|
|
|
QMap< int, QVector< QVector<QVector3D> > > mapData;
|
2025-11-11 09:44:56 +00:00
|
|
|
|
for (int nI = 0; nI < m_listCurve.size(); nI++)
|
2025-10-27 12:39:49 +00:00
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
if (m_exit)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
FileEntrySurface::SurfaceProperty surface = m_listCurve.at(nI);
|
2025-10-27 12:39:49 +00:00
|
|
|
|
int nStart = surface.start;
|
|
|
|
|
|
int nStop = surface.stop;
|
|
|
|
|
|
if (nStart == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
nStart = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (nStop == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
nStop = listLine.size();
|
|
|
|
|
|
}
|
|
|
|
|
|
QString strX = surface.x;
|
|
|
|
|
|
QString strY = surface.y;
|
|
|
|
|
|
QString strZ = surface.z;
|
|
|
|
|
|
|
|
|
|
|
|
double xInput = 0;
|
|
|
|
|
|
double yInput = 0;
|
|
|
|
|
|
double zInput = 0.0;
|
|
|
|
|
|
QVector< QVector<QVector3D> > listRowData;
|
|
|
|
|
|
int nRow = 0;
|
|
|
|
|
|
int nCol = 0;
|
|
|
|
|
|
for (int nJ = nStart; nJ < nStop; nJ += 3)
|
|
|
|
|
|
{
|
2025-11-11 09:44:56 +00:00
|
|
|
|
if (m_exit)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-27 12:39:49 +00:00
|
|
|
|
int x = listLine.at(nJ).toDouble();
|
|
|
|
|
|
int y = listLine.at(nJ + 1).toDouble();
|
|
|
|
|
|
double z = listLine.at(nJ + 2).toDouble();
|
|
|
|
|
|
|
|
|
|
|
|
if (strX == "x")
|
|
|
|
|
|
{
|
|
|
|
|
|
xInput = x;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (strX == "y")
|
|
|
|
|
|
{
|
|
|
|
|
|
xInput = y;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (strX == "z")
|
|
|
|
|
|
{
|
|
|
|
|
|
xInput = z;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (strY == "x")
|
|
|
|
|
|
{
|
|
|
|
|
|
yInput = x;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (strY == "y")
|
|
|
|
|
|
{
|
|
|
|
|
|
yInput = y;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (strY == "z")
|
|
|
|
|
|
{
|
|
|
|
|
|
yInput = z;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (strZ == "x")
|
|
|
|
|
|
{
|
|
|
|
|
|
zInput = x;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (strZ == "y")
|
|
|
|
|
|
{
|
|
|
|
|
|
zInput = y;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (strZ == "z")
|
|
|
|
|
|
{
|
|
|
|
|
|
zInput = z;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QVector3D v3d = QVector3D(xInput, yInput, zInput);
|
|
|
|
|
|
if (nRow == x)
|
|
|
|
|
|
{
|
|
|
|
|
|
int nIndex = listRowData.size() - 1;
|
|
|
|
|
|
QVector<QVector3D> listColData = listRowData[nIndex];
|
|
|
|
|
|
listColData.push_back(v3d);
|
|
|
|
|
|
listRowData.replace(nIndex, listColData);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
QVector<QVector3D> listColData;
|
|
|
|
|
|
listColData.push_back(v3d);
|
|
|
|
|
|
listRowData.push_back(listColData);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nRow = x;
|
|
|
|
|
|
nCol = y;
|
|
|
|
|
|
}
|
|
|
|
|
|
mapData.insert(nI, listRowData);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-11 09:44:56 +00:00
|
|
|
|
{
|
|
|
|
|
|
QMutexLocker locker(m_mutex);
|
|
|
|
|
|
m_panel->m_data.insert(t, mapData);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
file.close();
|
2025-11-15 12:47:53 +00:00
|
|
|
|
|
|
|
|
|
|
emit signalEndLoadData();
|
2025-10-27 12:39:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|