modified prop

This commit is contained in:
pimin 2025-11-11 17:44:56 +08:00
parent c8b53ec674
commit 9dd5b1f1f0
7 changed files with 1277 additions and 228 deletions

View File

@ -14,6 +14,25 @@ SurfacePanel::SurfacePanel(int index, const QString& filePath, QWidget* parent)
m_iMinY = 0; m_iMaxY = 0;
m_iMinZ = 0; m_iMaxZ = 0;
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;
m_xTitle = "";
m_yTitle = "";
m_zTitle = "";
m_time = -1.0;
m_thread = nullptr;
LOG_INFO("Created SurfacePanel {} for file: {}", index, filePath.toStdString());
}
@ -24,6 +43,25 @@ SurfacePanel::SurfacePanel(int index, std::shared_ptr<FileEntrySurface> fileEntr
m_iMinY = 0; m_iMaxY = 0;
m_iMinZ = 0; m_iMaxZ = 0;
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;
m_xTitle = "";
m_yTitle = "";
m_zTitle = "";
m_time = -1.0;
m_thread = nullptr;
if (fileEntry) {
LOG_INFO("Created SurfacePanel {} for chart: {}", index, fileEntry->GetName().toStdString());
// Override the title with chart name
@ -37,6 +75,50 @@ SurfacePanel::SurfacePanel(int index, std::shared_ptr<FileEntrySurface> fileEntr
SurfacePanel::~SurfacePanel()
{
LOG_INFO("Destroyed SurfacePanel {}", GetIndex());
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;
}
}
void SurfacePanel::RefreshPanel()
@ -53,51 +135,14 @@ void SurfacePanel::RefreshPanel()
void SurfacePanel::InitUI()
{
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);
m_Surface.activeTheme()->setType(Q3DTheme::Theme(2));
m_pSeries = new QSurface3DSeries;
m_pSeries->setDrawMode(QSurface3DSeries::DrawSurface);
m_Surface.addSeries(m_pSeries);
QWidget* containerHandle = QWidget::createWindowContainer(&m_Surface);
containerHandle->setAutoFillBackground(true);
containerHandle->setAttribute(Qt::WA_OpaquePaintEvent, true);
containerHandle->setAttribute(Qt::WA_NoSystemBackground, false);
containerHandle->setUpdatesEnabled(false);
containerHandle->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));
createSurface();
QHBoxLayout* mainLayout = new QHBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addWidget(containerHandle);
mainLayout->addWidget(m_surfaceContainer);
setLayout(mainLayout);
m_mutex = new QMutex;
}
QString SurfacePanel::GetTypeDisplayName() const
@ -124,43 +169,50 @@ void SurfacePanel::OnDataPanelUpdated(FileEntrySurface* fileEntry)
void SurfacePanel::OnTimeChanged(double time)
{
if (m_data.size() > 0)
m_time = time;
if (m_surface)
{
m_pSeries->dataProxy()->resetArray(nullptr);
QMutexLocker locker(m_mutex);
QMap< double, QMap< int, QVector< QVector<QVector3D> > > >::const_iterator ite = m_data.lowerBound(time);
if (ite == m_data.end())
if (m_data.size() > 0)
{
ite--;
}
m_pSeries->dataProxy()->resetArray(nullptr);
QMap< int, QVector< QVector<QVector3D> > > mapData = ite.value();
for (QMap< int, QVector< QVector<QVector3D> > >::Iterator it = mapData.begin(); it != mapData.end(); it++)
{
int nIndex = it.key();
QVector< QVector<QVector3D> > listRowData = it.value();
QSurfaceDataArray* data = new QSurfaceDataArray;
for (int nI = 0; nI < listRowData.size(); nI++)
QMap< double, QMap< int, QVector< QVector<QVector3D> > > >::const_iterator ite = m_data.lowerBound(time);
if (ite == m_data.end())
{
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;
ite--;
}
m_pSeries->dataProxy()->resetArray(data);
}
}
QMap< int, QVector< QVector<QVector3D> > > mapData = ite.value();
for (QMap< int, QVector< QVector<QVector3D> > >::Iterator it = mapData.begin(); it != mapData.end(); it++)
{
int nIndex = it.key();
QVector< QVector<QVector3D> > listRowData = it.value();
m_Surface.setShadowQuality(QAbstract3DGraph::ShadowQuality::ShadowQualityNone);
QSurfaceDataArray* data = new QSurfaceDataArray;
for (int nI = 0; nI < listRowData.size(); nI++)
{
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;
}
m_pSeries->dataProxy()->resetArray(data);
}
}
m_surface->setShadowQuality(QAbstract3DGraph::ShadowQuality::ShadowQualityNone);
}
}
void SurfacePanel::updateTitle(const QString & title)
@ -168,11 +220,18 @@ void SurfacePanel::updateTitle(const QString & title)
if (nullptr != dockWidget_)
{
dockWidget_->setWindowTitle(title);
connect(dockWidget_, &QDockWidget::visibilityChanged,
this, &SurfacePanel::onVisibilityChanged);
}
}
void SurfacePanel::updateTitleAxis(const QString & xTitle, const QString & yTitle, const QString & zTitle)
{
m_xTitle = xTitle;
m_yTitle = yTitle;
m_zTitle = zTitle;
m_p3DXAxis->setTitle(xTitle);
m_p3DXAxis->setTitleVisible(true);
m_p3DYAxis->setTitle(yTitle);
@ -190,6 +249,7 @@ void SurfacePanel::updateMinMaxX(float min, float max, int count)
if (count > 0)
{
m_countX = count;
m_p3DXAxis->setSegmentCount(count);
}
m_p3DXAxis->setRange(min, max);
@ -205,6 +265,7 @@ void SurfacePanel::updateMinMaxY(float min, float max, int count)
if (count > 0)
{
m_countY = count;
m_p3DYAxis->setSegmentCount(count);
}
m_p3DYAxis->setRange(min, max);
@ -220,6 +281,7 @@ void SurfacePanel::updateMinMaxZ(float min, float max, int count)
if (count > 0)
{
m_countZ = count;
m_p3DZAxis->setSegmentCount(count);
}
m_p3DZAxis->setRange(min, max);
@ -234,55 +296,236 @@ void SurfacePanel::updateParseFile(const QString & strFile, int nT, FileEntrySur
return;
}
m_data.clear();
m_pSeries->dataProxy()->resetArray(nullptr);
{
QMutexLocker locker(m_mutex);
m_data.clear();
m_pSeries->dataProxy()->resetArray(nullptr);
}
QFile file(strFile);
for (int nI = 0; nI < listCurve.size(); nI++)
{
FileEntrySurface::SurfaceProperty surface = listCurve.at(nI);
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);
m_thread->setMutex(m_mutex);
m_thread->start();
FinalParseFile();
}
void SurfacePanel::onVisibilityChanged(bool visible)
{
if (visible)
{
if (!m_surfaceContainer)
{
createSurface();
updateTitleAxis(m_xTitle, m_yTitle, m_zTitle);
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);
}
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)
{
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;
}
}
}
}
}
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);
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));
}
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))
{
for (int nI = 0; nI < listCurve.size(); nI++)
{
FileEntrySurface::SurfaceProperty surface = listCurve.at(nI);
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);
}
bool bResetAxisX = false;
if (m_iMaxX == m_iMinX)
{
bResetAxisX = true;
}
bool bResetAxisY = false;
if (m_iMaxZ == m_iMinZ)
{
bResetAxisY = true;
}
bool bResetAxisZ = false;
if (m_iMaxY == m_iMinY)
{
bResetAxisZ = true;
}
while (!file.atEnd())
while (!file.atEnd() && !m_exit)
{
QString strLine = file.readLine().simplified();
if (!strLine.isEmpty())
{
QStringList listLine = strLine.split(" ");
double t = listLine.at(nT).toDouble();
double t = listLine.at(m_nT).toDouble();
QMap< int, QVector< QVector<QVector3D> > > mapData;
for (int nI = 0; nI < listCurve.size(); nI++)
for (int nI = 0; nI < m_listCurve.size(); nI++)
{
FileEntrySurface::SurfaceProperty surface = listCurve.at(nI);
if (m_exit)
{
break;
}
FileEntrySurface::SurfaceProperty surface = m_listCurve.at(nI);
int nStart = surface.start;
int nStop = surface.stop;
if (nStart == 0)
@ -305,6 +548,11 @@ void SurfacePanel::updateParseFile(const QString & strFile, int nT, FileEntrySur
int nCol = 0;
for (int nJ = nStart; nJ < nStop; nJ += 3)
{
if (m_exit)
{
break;
}
int x = listLine.at(nJ).toDouble();
int y = listLine.at(nJ + 1).toDouble();
double z = listLine.at(nJ + 2).toDouble();
@ -368,25 +616,14 @@ void SurfacePanel::updateParseFile(const QString & strFile, int nT, FileEntrySur
}
mapData.insert(nI, listRowData);
}
m_data.insert(t, mapData);
{
QMutexLocker locker(m_mutex);
m_panel->m_data.insert(t, mapData);
}
}
}
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);
file.close();
}
}

View File

@ -6,9 +6,12 @@
#include <Q3DSurface>
#include <QValue3DAxis>
#include <QMutex>
using namespace QtDataVisualization;
class LoadDataThread;
class SurfacePanel : public DataPanel
{
Q_OBJECT
@ -46,6 +49,8 @@ public:
*/
void RefreshPanel() override;
void FinalParseFile();
protected:
/**
* @brief Initialize UI for curve-specific layout
@ -70,8 +75,12 @@ private:
void updateMinMaxZ(float min, float max, int count);
void updateParseFile(const QString& strFile, int nT, FileEntrySurface::SurfaceProperties listCurve);
void onVisibilityChanged(bool visible);
void createSurface();
private:
Q3DSurface m_Surface;
Q3DSurface *m_surface;
QWidget *m_surfaceContainer;
QSurface3DSeries* m_pSeries;
@ -86,6 +95,46 @@ private:
float m_iMinZ = 0;
float m_iMaxZ = 10;
int m_countX;
int m_countY;
int m_countZ;
QString m_xTitle;
QString m_yTitle;
QString m_zTitle;
QColor m_color;
double m_time;
QMutex *m_mutex;
LoadDataThread *m_thread;
public:
QMap< double, QMap< int, QVector< QVector<QVector3D> > > > m_data;
};
#include <QThread>
class LoadDataThread : public QThread
{
Q_OBJECT
public:
LoadDataThread(SurfacePanel *panel, QString file, int nT, FileEntrySurface::SurfaceProperties listCurve);
virtual void run();
void setMutex(QMutex *mutex)
{
m_mutex = mutex;
}
void requestExit() { m_exit = true; }
private:
SurfacePanel *m_panel;
QString m_file;
int m_nT;
FileEntrySurface::SurfaceProperties m_listCurve;
QMutex *m_mutex;
bool m_exit;
};

File diff suppressed because it is too large Load Diff

View File

@ -38,6 +38,7 @@ private:
private:
class QtTreePropertyBrowser* browser_{ nullptr };
class QtEnumPropertyManager* enumManager_{ nullptr };
class QtIntPropertyManager* intManager_{ nullptr };
class QtBoolPropertyManager* boolManager_{ nullptr };
class QtDoublePropertyManager* doubleManager_{ nullptr };
@ -66,5 +67,8 @@ private:
// Write-back hooks for color properties
QMap<class QtProperty*, std::function<void(const QColor&)>> colorSetters_;
QMap<class QtProperty*, std::function<void(const QString&)>> stringSetters_;
QMap<class QtProperty*, std::function<void(const int&)>> intSetters_;
QMap<class QtProperty*, std::function<void(const double&)>> doubleSetters_;
};

View File

@ -21,9 +21,9 @@ void CommandExecutor::Execute(WorkSpace* ws, WorkSpace::CommandWhen when) {
}
}
};
if (!cmd_.rawArgs.isEmpty()) {
pushArgs(cmd_.rawArgs);
}
//if (!cmd_.rawArgs.isEmpty()) {
// pushArgs(cmd_.rawArgs);
//}
const QString programLower = cmd_.program.toLower();
if (!cmd_.path.isEmpty()) {

View File

@ -469,6 +469,13 @@ bool FileEntryTable::ParseFiles(const tinyxml2::XMLElement * element)
return true;
}
void FileEntryCurve::SetCurveProperty(int index, const CurveProperty & prop)
{
if (index >= 0 && index < curveProperties_.size()) {
curveProperties_[index] = prop;
}
}
// FileEntryCurve SaveFiles implementation
bool FileEntryCurve::SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc) {
if (!scene || !doc) {
@ -515,6 +522,13 @@ bool FileEntryCurve::SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocumen
return true;
}
void FileEntryLight::SetLightProperty(int index, const LightRowProperty & prop)
{
if (index >= 0 && index < lightProperties_.size()) {
lightProperties_[index] = prop;
}
}
// FileEntryLight SaveFiles implementation
bool FileEntryLight::SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc) {
if (!scene || !doc) {
@ -715,6 +729,54 @@ const FileEntryPolar::ChartProperties& FileEntryPolar::GetChartProperties() cons
return chartProperties_;
}
void FileEntryPolar::UpdateChartProperties(const QString & key, QVariant var)
{
if (key == "AngularCount")
{
chartProperties_.AngularCount = var.toInt();
}
else if (key == "RadialCount")
{
chartProperties_.RadialCount = var.toInt();
}
else if (key == "AngularTitle")
{
chartProperties_.AngularTitle = var.toString();
}
else if (key == "RadialTitle")
{
chartProperties_.RadialTitle = var.toString();
}
else if (key == "AngularMin")
{
chartProperties_.AngularMin = var.toDouble();
}
else if (key == "AngularMax")
{
chartProperties_.AngularMax = var.toDouble();
}
else if (key == "RadialMin")
{
chartProperties_.RadialMin = var.toDouble();
}
else if (key == "RadialMax")
{
chartProperties_.RadialMax = var.toDouble();
}
else if (key == "AngularUnit")
{
chartProperties_.AngularUnit = var.toString();
}
else if (key == "RadialUnit")
{
chartProperties_.RadialUnit = var.toString();
}
else if (key == "timeParam")
{
chartProperties_.timeParam = var.toDouble();
}
}
void FileEntryPolar::AddLineProperty(const LineProperty& line) {
lineProperties_.append(line);
}

View File

@ -2,6 +2,7 @@
#include <QString>
#include <QColor>
#include <QVariant>
#include "xml/tinyxml2.h"
enum class FileEntryType {
@ -166,6 +167,7 @@ public:
void AddCurveProperty(const CurveProperty& prop) { curveProperties_.append(prop); }
void RemoveCurveProperty(int index) { curveProperties_.removeAt(index); }
void SetCurveProperty(int index, const CurveProperty& prop);
const CurveProperties& GetCurveProperties() const { return curveProperties_; }
FileEntryCurve* AsCurve() override { return this; }
@ -297,6 +299,7 @@ public:
void AddLightProperty(const LightRowProperty& prop) { lightProperties_.append(prop); }
void RemoveLightProperty(int index) { lightProperties_.removeAt(index); }
void SetLightProperty(int index, const LightRowProperty& prop);
const LightRowProperties& GetLightProperties() const { return lightProperties_; }
FileEntryLight* AsLight() override { return this; }
@ -341,6 +344,8 @@ public:
void SetChartProperties(const ChartProperties& properties);
const ChartProperties& GetChartProperties() const;
void UpdateChartProperties(const QString& key, QVariant var);
// Line properties management
void AddLineProperty(const LineProperty& line);
void RemoveLineProperty(int index);