ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
G3PointPlots.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "G3PointPlots.h"
9 
10 #include "ui_G3PointPlots.h"
11 
12 // Qt5/Qt6 Compatibility
13 #include <QtCompat.h>
14 
15 // CCPluginAPI
16 #include <ecvPersistentSettings.h>
17 
19 #include <ecvFileUtils.h>
20 
21 // qcc_io
22 #include <ImageFileFilter.h>
23 
24 #include <QSettings>
25 
26 #include "AnglesCustomPlot.h"
27 #include "WolmanCustomPlot.h"
28 
29 G3PointPlots::G3PointPlots(QString title, QWidget* parent)
30  : QWidget(parent), ui(new Ui::G3PointPlots) {
31  ui->setupUi(this);
32 
33  readSettings();
34 
35  setWindowTitle(title);
36 
37  connect(this->ui->exportCSVToolButton, &QToolButton::clicked, this,
39  connect(this->ui->exportImage, &QToolButton::clicked, this,
41 }
42 
44 
45 void G3PointPlots::closeEvent(QCloseEvent* event) {
46  QSettings settings("OSERen", "qG3Point");
47  settings.setValue("G3PointPlots/geometry", saveGeometry());
48  // settings.setValue("windowState", saveState());
49  QWidget::closeEvent(event);
50 }
51 
53  QSettings settings("OSERen", "qG3Point");
54  restoreGeometry(settings.value("G3PointPlots/geometry").toByteArray());
55 }
56 
57 void G3PointPlots::addToTabWidget(QWidget* widget) {
58  this->ui->tabWidget->addTab(widget, widget->windowTitle());
59  this->ui->tabWidget->setCurrentWidget(widget);
60 
61  if (widget->property("TypeOfCustomPlot").toString() == "AnglesCustomPlot") {
62  connect(static_cast<AnglesCustomPlot*>(widget),
65  } else if (widget->property("TypeOfCustomPlot").toString() ==
66  "WolmanCustomPlot") {
67  connect(static_cast<WolmanCustomPlot*>(widget),
70  }
71 }
72 
74  this->ui->tabWidget->currentWidget()->deleteLater();
75 }
76 
77 template <typename SharedDataContainer>
79  SharedDataContainer container,
80  const Eigen::Array3d* dq_final,
81  const Eigen::Array3d* edq) const {
82  QFile file(filename);
83  if (!file.open(QFile::WriteOnly | QFile::Text)) {
84  CVLog::Warning(QString("[SF/SF] Failed to save plot to file '%1'")
85  .arg(filename));
86  return false;
87  }
88 
89  QTextStream stream(&file);
90  stream.setRealNumberPrecision(12);
91  stream.setRealNumberNotation(QTextStream::FixedNotation);
92 
93  // header
94  if (dq_final) // WolmanCustomPlot
95  {
96  stream << "# D10 [mm], D50 [mm], D90 [mm]" << QtCompat::endl;
97  stream << (*dq_final)(0) << " " << (*dq_final)(1) << " "
98  << (*dq_final)(2) << QtCompat::endl;
99  stream << "# std(D10) [mm], std(D50) [mm], std(D90) [mm]"
100  << QtCompat::endl;
101  stream << (*edq)(0) << " " << (*edq)(1) << " " << (*edq)(2)
102  << QtCompat::endl;
103  stream << "diameter [m], pdf" << QtCompat::endl;
104  } else // AnglesCustomPlot
105  {
106  stream << "angle [degree], counts" << QtCompat::endl;
107  }
108 
109  // data
110  {
111  for (auto item : *container) {
112  stream << item.key << " " << item.value << QtCompat::endl;
113  }
114  }
115 
116  file.close();
117 
118  CVLog::Print(QString("[SF/SF] File '%1' saved").arg(filename));
119 
120  return true;
121 }
122 
123 typedef QSharedPointer<QCPBarsDataContainer> SharedBarsDataContainer;
124 typedef QSharedPointer<QCPGraphDataContainer> SharedGraphDataContainer;
125 
127  // get current tab widget
128  QWidget* currentWidget = this->ui->tabWidget->currentWidget();
129 
130  // persistent settings
131  QSettings settings;
132  settings.beginGroup(ecvPS::SaveFile());
133  QString currentPath =
135  .toString();
136 
137  currentPath += QString("/") + currentWidget->windowTitle() + ".csv";
138 
139  // ask for a filename
140  QString filename = QFileDialog::getSaveFileName(this, "Select output file",
141  currentPath, "*.csv");
142  if (filename.isEmpty()) {
143  // process cancelled by user
144  return;
145  }
146 
147  // save last saving location
148  settings.setValue(ecvPS::CurrentPath(), QFileInfo(filename).absolutePath());
149  settings.endGroup();
150 
151  if (currentWidget->property("TypeOfCustomPlot").toString() ==
152  "AnglesCustomPlot") {
153  Eigen::Array3d dq_final;
154  Eigen::Array3d edq;
155  exportToCSV<SharedBarsDataContainer>(
156  filename,
157  static_cast<AnglesCustomPlot*>(currentWidget)->dataContainer());
158  } else if (currentWidget->property("TypeOfCustomPlot").toString() ==
159  "WolmanCustomPlot") {
160  WolmanCustomPlot* wolmanCustomPlot =
161  static_cast<WolmanCustomPlot*>(currentWidget);
162  exportToCSV<SharedGraphDataContainer>(
163  filename, wolmanCustomPlot->dataContainer(),
164  &wolmanCustomPlot->m_dq_final, &wolmanCustomPlot->m_edq);
165  }
166 }
167 
169  QWidget* currentWidget = this->ui->tabWidget->currentWidget();
170 
171  // persistent settings
172  QSettings settings;
173  settings.beginGroup(ecvPS::SaveFile());
174  QString currentPath =
176  .toString();
177 
178  QString outputFilename = ImageFileFilter::GetSaveFilename(
179  "Select output file", currentWidget->windowTitle(), currentPath,
180  this);
181 
182  if (outputFilename.isEmpty()) {
183  // process cancelled by user (or error)
184  return;
185  }
186 
187  // save current export path to persistent settings
188  settings.setValue(ecvPS::CurrentPath(),
189  QFileInfo(outputFilename).absolutePath());
190  settings.endGroup();
191 
192  // save the widget as an image file
193  QPixmap image = currentWidget->grab();
194  if (image.save(outputFilename)) {
195  CVLog::Print(QString("[SF/SF] Image '%1' successfully saved")
196  .arg(outputFilename));
197  } else {
198  CVLog::Error(QString("Failed to save file '%1'").arg(outputFilename));
199  }
200 }
MouseEvent event
std::string filename
std::shared_ptr< core::Tensor > image
QSharedPointer< QCPBarsDataContainer > SharedBarsDataContainer
QSharedPointer< QCPGraphDataContainer > SharedGraphDataContainer
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
static bool Print(const char *format,...)
Prints out a formatted message in console.
Definition: CVLog.cpp:113
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Definition: CVLog.cpp:143
void readSettings()
void addToTabWidget(QWidget *widget)
void onExportToCSV()
G3PointPlots(QString title, QWidget *parent=nullptr)
qCC_db
void closeCurrentWidget()
void onExportToImage()
bool exportToCSV(QString filename, SharedDataContainer container, const Eigen::Array3d *dq_final=nullptr, const Eigen::Array3d *edq=nullptr) const
void closeEvent(QCloseEvent *event) override
static QString GetSaveFilename(const QString &dialogTitle, const QString &baseName, const QString &imageSavePath, QWidget *parentWidget=nullptr)
Helper: select an output image filename.
Eigen::Array3d m_dq_final
Eigen::Array3d m_edq
QSharedPointer< QCPGraphDataContainer > dataContainer()
static const QString CurrentPath()
static const QString SaveFile()
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
QString defaultDocPath()
Shortcut for getting the documents location path.
Definition: ecvFileUtils.h:30