Wolman + Angles (dip and azimuth) implemented
This commit is contained in:
+6
-1
@@ -11,7 +11,12 @@ if ( PLUGIN_G3POINT )
|
||||
|
||||
AddPlugin( NAME ${PROJECT_NAME} )
|
||||
|
||||
set(QG3POINT_PLUGIN_VERSION "0.3+")
|
||||
target_sources(G3PointPlugin
|
||||
PRIVATE
|
||||
ui/WolmanCustomPlot.ui
|
||||
)
|
||||
|
||||
set(QG3POINT_PLUGIN_VERSION "0.4")
|
||||
|
||||
add_subdirectory( include )
|
||||
add_subdirectory( src )
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 471 B |
Binary file not shown.
|
After Width: | Height: | Size: 421 B |
@@ -0,0 +1,44 @@
|
||||
#ifndef ANGLESCUSTOMPLOT_H
|
||||
#define ANGLESCUSTOMPLOT_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <qcustomplot.h>.h>
|
||||
|
||||
namespace Ui {
|
||||
class AnglesCustomPlot;
|
||||
}
|
||||
|
||||
class AnglesCustomPlot : public QCustomPlot
|
||||
{
|
||||
|
||||
public:
|
||||
explicit AnglesCustomPlot(const QVector<double>& data, const QString& xLabel, int nbBins,
|
||||
QWidget *parent = nullptr);
|
||||
~AnglesCustomPlot();
|
||||
|
||||
bool computeHistogram(const QVector<double>& data);
|
||||
|
||||
void createQCPBars(const QString &xLabel);
|
||||
|
||||
void rescale();
|
||||
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
|
||||
QSharedPointer<QCPBarsDataContainer> dataContainer(){return m_bars->data();}
|
||||
|
||||
private:
|
||||
Ui::AnglesCustomPlot *ui;
|
||||
|
||||
QVector<double> m_axis;
|
||||
|
||||
QVector<double> m_histogram;
|
||||
|
||||
QString m_label;
|
||||
|
||||
QCPBars* m_bars;
|
||||
|
||||
int m_nbBins;
|
||||
};
|
||||
|
||||
#endif // ANGLESCUSTOMPLOT_H
|
||||
@@ -1,12 +1,14 @@
|
||||
|
||||
target_sources( ${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}/ActionA.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointAction.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3Point.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointDialog.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/GrainsAsEllipsoids.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/qG3PointDisclaimer.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointDisclaimer.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/AnglesCustomPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/WolmanCustomPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointPlots.h
|
||||
)
|
||||
|
||||
target_include_directories( ${PROJECT_NAME}
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
|
||||
#include <GrainsAsEllipsoids.h>
|
||||
|
||||
#include <AnglesCustomPlot.h>
|
||||
|
||||
#include <G3PointPlots.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
class ccMainAppInterface;
|
||||
@@ -36,6 +40,8 @@ public:
|
||||
bool cluster();
|
||||
void fit();
|
||||
void exportResults();
|
||||
void plots();
|
||||
void showWolman(const Eigen::ArrayXf& d_sample);
|
||||
bool wolman();
|
||||
bool angles();
|
||||
bool processNewStacks(std::vector<std::vector<int>>& newStacks, int pointCount);
|
||||
@@ -107,6 +113,8 @@ private:
|
||||
|
||||
static std::shared_ptr<G3PointAction> s_g3PointAction;
|
||||
|
||||
QSharedPointer<GrainsAsEllipsoids> m_grainsAsEllipsoids;
|
||||
static std::shared_ptr<G3PointPlots> s_g3PointPlots;
|
||||
|
||||
GrainsAsEllipsoids* m_grainsAsEllipsoids;
|
||||
};
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class qG3PointDialog;
|
||||
class G3PointDialog;
|
||||
}
|
||||
|
||||
class G3PointDialog : public QDialog
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
double getMinFlatness();
|
||||
int getNMin();
|
||||
int getkNN();
|
||||
int getWolmanNbIter();
|
||||
int getAnglesNbBins();
|
||||
double getRadiusFactor();
|
||||
|
||||
bool isSteepestSlope();
|
||||
@@ -73,7 +75,7 @@ signals:
|
||||
void glPointSize(int size);
|
||||
|
||||
private:
|
||||
Ui::qG3PointDialog *ui;
|
||||
Ui::G3PointDialog *ui;
|
||||
};
|
||||
|
||||
#endif // QG3POINTDIALOG_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef QG3POINTDISCLAIMER_H
|
||||
#define QG3POINTDISCLAIMER_H
|
||||
#ifndef G3POINTDISCLAIMER_H
|
||||
#define G3POINTDISCLAIMER_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -9,13 +9,13 @@ namespace Ui {
|
||||
class G3PointDisclaimer;
|
||||
}
|
||||
|
||||
class qG3PointDisclaimer : public QDialog
|
||||
class G3PointDisclaimer : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit qG3PointDisclaimer(QWidget *parent = nullptr);
|
||||
~qG3PointDisclaimer();
|
||||
explicit G3PointDisclaimer(QWidget *parent = nullptr);
|
||||
~G3PointDisclaimer();
|
||||
|
||||
static bool show(ccMainAppInterface* app);
|
||||
|
||||
@@ -26,4 +26,4 @@ private:
|
||||
Ui::G3PointDisclaimer *ui;
|
||||
};
|
||||
|
||||
#endif // QG3POINTDISCLAIMER_H
|
||||
#endif // G3POINTDISCLAIMER_H
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef G3POINTPLOTS_H
|
||||
#define G3POINTPLOTS_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <qcustomplot.h>
|
||||
|
||||
namespace Ui {
|
||||
class G3PointPlots;
|
||||
}
|
||||
|
||||
class G3PointPlots : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit G3PointPlots(QString title, QWidget *parent = nullptr);
|
||||
~G3PointPlots();
|
||||
|
||||
void readSettings();
|
||||
|
||||
void addToTabWidget(QWidget* widget);
|
||||
|
||||
template<typename SharedDataContainer>
|
||||
bool exportToCSV(QString filename, SharedDataContainer container) const;
|
||||
|
||||
void onExportToCSV();
|
||||
|
||||
void onExportToImage();
|
||||
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
Ui::G3PointPlots *ui;
|
||||
};
|
||||
|
||||
#endif // G3POINTPLOTS_H
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
GrainsAsEllipsoids(ccMainAppInterface *app);
|
||||
|
||||
GrainsAsEllipsoids(ccPointCloud *cloud, ccMainAppInterface* app, const std::vector<std::vector<int> >& stacks, const RGBAColorsTableType& colors);
|
||||
~GrainsAsEllipsoids();
|
||||
|
||||
//! Set the path for shaders
|
||||
void setShaderPath();
|
||||
|
||||
@@ -1,21 +1,77 @@
|
||||
#ifndef WOLMANCUSTOMPLOT_H
|
||||
#define WOLMANCUSTOMPLOT_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <qcustomplot.h>
|
||||
|
||||
// Eigen
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
namespace Ui {
|
||||
class WolmanCustomPlot;
|
||||
}
|
||||
|
||||
class WolmanCustomPlot : public QCustomPlot
|
||||
//! QCustomPlot: vertical bar with text along side
|
||||
class QCPBarsWithText : public QCPBars
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WolmanCustomPlot(QWidget *parent = nullptr);
|
||||
~WolmanCustomPlot();
|
||||
|
||||
QCPBarsWithText(QCPAxis* keyAxis, QCPAxis* valueAxis) : QCPBars(keyAxis,valueAxis), m_textOnTheLeft(false) {}
|
||||
|
||||
void setText(QString text) { m_text = QStringList(text); }
|
||||
void appendText(QString text) { m_text.append(text); }
|
||||
void setTextAlignment(bool left) { m_textOnTheLeft = left; }
|
||||
|
||||
protected:
|
||||
|
||||
QStringList m_text;
|
||||
bool m_textOnTheLeft;
|
||||
|
||||
// reimplemented virtual draw method
|
||||
virtual void draw(QCPPainter *painter)
|
||||
{
|
||||
if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
|
||||
|
||||
//switch to standard display
|
||||
QCPBars::draw(painter);
|
||||
|
||||
int fontHeight = painter->fontMetrics().height();
|
||||
|
||||
if (!data()->isEmpty())
|
||||
{
|
||||
double& key = data()->begin()->key;
|
||||
double& value = data()->begin()->value;
|
||||
QPointF P = coordsToPixels(key, value);
|
||||
//apply a small shift
|
||||
int margin = 5; //in pixels
|
||||
if (m_textOnTheLeft)
|
||||
margin = -margin;
|
||||
P.setX(P.x() + margin);
|
||||
//we draw at the 'base' line
|
||||
P.setY(P.y() + fontHeight);
|
||||
|
||||
for (int i=0; i<m_text.size(); ++i)
|
||||
{
|
||||
QPointF Pstart = P;
|
||||
if (m_textOnTheLeft)
|
||||
Pstart.setX(P.x() - painter->fontMetrics().width(m_text[i]));
|
||||
painter->drawText(Pstart,m_text[i]);
|
||||
P.setY(P.y() + fontHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class WolmanCustomPlot : public QWidget
|
||||
{
|
||||
public:
|
||||
WolmanCustomPlot(const Eigen::ArrayXf& d_sample);
|
||||
|
||||
QSharedPointer<QCPGraphDataContainer> dataContainer(){return m_graph->data();}
|
||||
|
||||
QCPGraph* m_graph;
|
||||
|
||||
private:
|
||||
Ui::WolmanCustomPlot *ui;
|
||||
|
||||
@@ -2,5 +2,7 @@
|
||||
<qresource prefix="/CC/plugin/G3PointPlugin">
|
||||
<file>info.json</file>
|
||||
<file>images/icon.png</file>
|
||||
<file>images/smallCSVFile.png</file>
|
||||
<file>images/dbImageSymbol.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
#include "AnglesCustomPlot.h"
|
||||
#include "ui_AnglesCustomPlot.h"
|
||||
|
||||
#include <ScalarField.h>
|
||||
#include <ccLog.h>
|
||||
|
||||
AnglesCustomPlot::AnglesCustomPlot(const QVector<double> &data, const QString &xLabel, int nbBins, QWidget *parent):
|
||||
ui(new Ui::AnglesCustomPlot),
|
||||
m_label(xLabel),
|
||||
m_bars(nullptr),
|
||||
m_nbBins(nbBins)
|
||||
{
|
||||
setProperty("TypeOfCustomPlot", "AnglesCustomPlot");
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowTitle(m_label);
|
||||
|
||||
computeHistogram(data);
|
||||
|
||||
createQCPBars(m_label + " [°]");
|
||||
|
||||
m_bars->rescaleAxes();
|
||||
}
|
||||
|
||||
AnglesCustomPlot::~AnglesCustomPlot()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
//! Default number of classes for associated histogram
|
||||
static const unsigned MAX_HISTOGRAM_SIZE = 512;
|
||||
|
||||
bool AnglesCustomPlot::computeHistogram(const QVector<double>& data)
|
||||
{
|
||||
double minData = *std::min_element(data.begin(), data.end());
|
||||
double maxData = *std::max_element(data.begin(), data.end());
|
||||
double range = maxData - minData;
|
||||
|
||||
if (range == 0 || data.size() == 0)
|
||||
{
|
||||
//can't build histogram of a flat field
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned count = data.size();
|
||||
unsigned numberOfBins;
|
||||
if (m_nbBins == -1) // compute number of bins automatically
|
||||
{
|
||||
numberOfBins = static_cast<unsigned>(ceil(sqrt(static_cast<double>(count))));
|
||||
numberOfBins = std::max<unsigned>(std::min<unsigned>(numberOfBins, MAX_HISTOGRAM_SIZE), 4);
|
||||
}
|
||||
else // use number of bins
|
||||
{
|
||||
numberOfBins = m_nbBins;
|
||||
}
|
||||
|
||||
m_axis.resize(numberOfBins);
|
||||
for (unsigned i = 0; i < numberOfBins; i++)
|
||||
{
|
||||
m_axis[i] = minData + i * range / numberOfBins;
|
||||
}
|
||||
|
||||
//reserve memory
|
||||
try
|
||||
{
|
||||
m_histogram.resize(numberOfBins);
|
||||
}
|
||||
catch (const std::bad_alloc&)
|
||||
{
|
||||
ccLog::Warning("[computeHistogram] Failed to allocate histogram!");
|
||||
}
|
||||
|
||||
std::fill(m_histogram.begin(), m_histogram.end(), 0);
|
||||
|
||||
//compute histogram
|
||||
ScalarType step = static_cast<ScalarType>(numberOfBins) / range;
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
{
|
||||
const ScalarType& val = data[i];
|
||||
|
||||
if (CCCoreLib::ScalarField::ValidValue(val))
|
||||
{
|
||||
unsigned bin = static_cast<unsigned>((val - minData) * step);
|
||||
++m_histogram[std::min(bin, numberOfBins - 1)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnglesCustomPlot::createQCPBars(const QString& xLabel)
|
||||
{
|
||||
//clear previous display
|
||||
if (m_bars)
|
||||
{
|
||||
this->removePlottable(m_bars);
|
||||
m_bars = nullptr;
|
||||
}
|
||||
|
||||
m_bars = new QCPBars(xAxis, yAxis);
|
||||
m_bars->setAntialiased(false); // gives more crisp, pixel aligned bar borders
|
||||
m_bars->setPen(QPen(QColor(0, 168, 140).lighter(130)));
|
||||
m_bars->setBrush(QColor(0, 168, 140));
|
||||
m_bars->setWidth(m_axis[1] - m_axis[0]);
|
||||
m_bars->setData(m_axis, m_histogram);
|
||||
xAxis->setLabel(xLabel);
|
||||
yAxis->setLabel("Counts");
|
||||
setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
|
||||
}
|
||||
|
||||
void AnglesCustomPlot::rescale()
|
||||
{
|
||||
// set ranges appropriate to show data
|
||||
if (m_bars)
|
||||
{
|
||||
m_bars->rescaleAxes();
|
||||
replot();
|
||||
}
|
||||
}
|
||||
|
||||
void AnglesCustomPlot::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
rescale();
|
||||
}
|
||||
QCustomPlot::mouseDoubleClickEvent(event);
|
||||
}
|
||||
+4
-2
@@ -1,10 +1,12 @@
|
||||
|
||||
target_sources( ${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}/ActionA.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointAction.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3Point.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointDialog.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/GrainsAsEllipsoids.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/qG3PointDisclaimer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointDisclaimer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/AnglesCustomPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/WolmanCustomPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointPlots.cpp
|
||||
)
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
|
||||
#include "G3Point.h"
|
||||
|
||||
#include "ActionA.h"
|
||||
#include "G3PointAction.h"
|
||||
|
||||
ccHObject* G3PointFactory::buildObject(const QString& metaName)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "ActionA.h"
|
||||
#include "G3PointAction.h"
|
||||
|
||||
// CCPluginAPI
|
||||
#include <ccMainAppInterface.h>
|
||||
@@ -42,13 +42,15 @@
|
||||
#include <set>
|
||||
|
||||
#include <G3PointDialog.h>
|
||||
#include <qG3PointDisclaimer.h>
|
||||
#include <G3PointDisclaimer.h>
|
||||
#include <WolmanCustomPlot.h>
|
||||
|
||||
namespace G3Point
|
||||
{
|
||||
std::shared_ptr<G3PointAction> G3PointAction::s_g3PointAction;
|
||||
|
||||
std::shared_ptr<G3PointPlots> G3PointAction::s_g3PointPlots;
|
||||
|
||||
G3PointAction::G3PointAction(ccPointCloud *cloud, ccMainAppInterface *app)
|
||||
: m_app(app)
|
||||
, m_dlg(nullptr)
|
||||
@@ -71,9 +73,11 @@ G3PointAction::~G3PointAction()
|
||||
void G3PointAction::GetG3PointAction(ccPointCloud *cloud, ccMainAppInterface *app)
|
||||
{
|
||||
//disclaimer accepted?
|
||||
if (!qG3PointDisclaimer::show(app))
|
||||
if (!G3PointDisclaimer::show(app))
|
||||
return;
|
||||
|
||||
s_g3PointPlots.reset(new G3PointPlots(cloud->getName()));
|
||||
|
||||
if (!s_g3PointAction) // create the singleton if needed
|
||||
{
|
||||
s_g3PointAction.reset(new G3PointAction(cloud, app));
|
||||
@@ -613,8 +617,12 @@ bool G3PointAction::exportLocalMaximaAsCloud(const Eigen::ArrayXi& localMaximumI
|
||||
m_app->removeFromDB(child, true);
|
||||
}
|
||||
|
||||
parent->addChild(cloud, ccHObject::DP_PARENT_OF_OTHER, 0);
|
||||
// parent->addChild(cloud, ccHObject::DP_PARENT_OF_OTHER, 0);
|
||||
// m_app->addToDB(cloud);
|
||||
m_cloud->addChild(cloud);
|
||||
m_app->addToDB(cloud);
|
||||
|
||||
|
||||
cloud->setEnabled(false);
|
||||
|
||||
return true;
|
||||
@@ -1008,24 +1016,26 @@ void G3PointAction::fit()
|
||||
|
||||
// plot display grains as ellipsoids
|
||||
m_grainColors.reset(new RGBAColorsTableType(getRandomColors(m_localMaximumIndexes.size())));
|
||||
m_grainsAsEllipsoids.reset(new GrainsAsEllipsoids(m_cloud, m_app, m_stacks, *m_grainColors));
|
||||
m_grainsAsEllipsoids = new GrainsAsEllipsoids(m_cloud, m_app, m_stacks, *m_grainColors);
|
||||
m_grainsAsEllipsoids->setName("g3point_ellipsoids");
|
||||
|
||||
// add connections with the dialog
|
||||
connect(m_dlg, &G3PointDialog::onlyOneClicked, m_grainsAsEllipsoids.data(), &GrainsAsEllipsoids::showOnlyOne);
|
||||
connect(m_dlg, &G3PointDialog::allClicked, m_grainsAsEllipsoids.data(), &GrainsAsEllipsoids::showAll);
|
||||
connect(m_dlg, &G3PointDialog::onlyOneChanged, m_grainsAsEllipsoids.data(), &GrainsAsEllipsoids::setOnlyOne);
|
||||
connect(m_dlg, &G3PointDialog::transparencyChanged, m_grainsAsEllipsoids.data(), &GrainsAsEllipsoids::setTransparency);
|
||||
connect(m_dlg, &G3PointDialog::drawSurfaces, m_grainsAsEllipsoids.data(), &GrainsAsEllipsoids::drawSurfaces);
|
||||
connect(m_dlg, &G3PointDialog::drawLines, m_grainsAsEllipsoids.data(), &GrainsAsEllipsoids::drawLines);
|
||||
connect(m_dlg, &G3PointDialog::drawPoints, m_grainsAsEllipsoids.data(), &GrainsAsEllipsoids::drawPoints);
|
||||
connect(m_dlg, &G3PointDialog::glPointSize, m_grainsAsEllipsoids.data(), &GrainsAsEllipsoids::setGLPointSize);
|
||||
connect(m_dlg, &G3PointDialog::onlyOneClicked, m_grainsAsEllipsoids, &GrainsAsEllipsoids::showOnlyOne);
|
||||
connect(m_dlg, &G3PointDialog::allClicked, m_grainsAsEllipsoids, &GrainsAsEllipsoids::showAll);
|
||||
connect(m_dlg, &G3PointDialog::onlyOneChanged, m_grainsAsEllipsoids, &GrainsAsEllipsoids::setOnlyOne);
|
||||
connect(m_dlg, &G3PointDialog::transparencyChanged, m_grainsAsEllipsoids, &GrainsAsEllipsoids::setTransparency);
|
||||
connect(m_dlg, &G3PointDialog::drawSurfaces, m_grainsAsEllipsoids, &GrainsAsEllipsoids::drawSurfaces);
|
||||
connect(m_dlg, &G3PointDialog::drawLines, m_grainsAsEllipsoids, &GrainsAsEllipsoids::drawLines);
|
||||
connect(m_dlg, &G3PointDialog::drawPoints, m_grainsAsEllipsoids, &GrainsAsEllipsoids::drawPoints);
|
||||
connect(m_dlg, &G3PointDialog::glPointSize, m_grainsAsEllipsoids, &GrainsAsEllipsoids::setGLPointSize);
|
||||
|
||||
m_dlg->setOnlyOneMax(m_stacks.size());
|
||||
m_dlg->emitSignals(); // force to send parameters to m_grainsAsEllipsoids
|
||||
|
||||
m_cloud->getParent()->addChild(m_grainsAsEllipsoids.data());
|
||||
m_app->addToDB(m_cloud);
|
||||
// m_cloud->getParent()->addChild(m_grainsAsEllipsoids.get());
|
||||
// m_app->addToDB(m_cloud);
|
||||
m_cloud->addChild(m_grainsAsEllipsoids);
|
||||
m_app->addToDB(m_grainsAsEllipsoids);
|
||||
|
||||
m_app->updateUI();
|
||||
}
|
||||
@@ -1084,33 +1094,25 @@ double std_dev(const T &vec)
|
||||
return std::sqrt((vec - vec.mean()).square().sum() / (vec.size() - 1));
|
||||
}
|
||||
|
||||
void showWolman(const Eigen::ArrayXf& d_sample)
|
||||
void G3PointAction::plots()
|
||||
{
|
||||
angles();
|
||||
}
|
||||
|
||||
void G3PointAction::showWolman(const Eigen::ArrayXf& d_sample)
|
||||
{
|
||||
// QCustomPlot
|
||||
WolmanCustomPlot* wolmanCustomPlot = new WolmanCustomPlot();
|
||||
QCPGraph* graph = wolmanCustomPlot->addGraph();
|
||||
QVector<double> x_data(d_sample.size());
|
||||
QVector<double> y_data(d_sample.size());
|
||||
for (int k = 0; k < d_sample.size(); k++)
|
||||
{
|
||||
x_data[k] = d_sample(k);
|
||||
y_data[k] = (static_cast<double>(k)) / static_cast<double>(d_sample.size());
|
||||
}
|
||||
std::sort(x_data.begin(), x_data.end());
|
||||
graph->setData(x_data, y_data);
|
||||
graph->rescaleAxes();
|
||||
// give the axes some labels:
|
||||
wolmanCustomPlot->xAxis->setScaleType(QCPAxis::stLogarithmic);
|
||||
wolmanCustomPlot->xAxis->setLabel("Diameter [mm]");
|
||||
wolmanCustomPlot->yAxis->setLabel("CDF");
|
||||
wolmanCustomPlot->show();
|
||||
if (!s_g3PointPlots)
|
||||
s_g3PointPlots.reset(new G3PointPlots(m_cloud->getName()));
|
||||
s_g3PointPlots->addToTabWidget(new WolmanCustomPlot(d_sample));
|
||||
s_g3PointPlots->show();
|
||||
}
|
||||
|
||||
bool G3PointAction::wolman()
|
||||
{
|
||||
int n_iter = 10;
|
||||
int n_iter = m_dlg->getWolmanNbIter();
|
||||
|
||||
if (m_grainsAsEllipsoids.isNull())
|
||||
if (!m_grainsAsEllipsoids)
|
||||
{
|
||||
ccLog::Error("[G3PointAction::wolman] no ellipsoid, not possible to do Wolman analysis");
|
||||
return false;
|
||||
@@ -1169,7 +1171,7 @@ bool G3PointAction::wolman()
|
||||
{
|
||||
float r0 = dist(urbg);
|
||||
float r1 = dist(urbg);
|
||||
std::cout << r0 << ", " << r1 << "," << std::endl;
|
||||
// std::cout << r0 << ", " << r1 << "," << std::endl;
|
||||
x_grid = arange(x.minCoeff() - r0 * dx, x.maxCoeff(), dx);
|
||||
y_grid = arange(y.minCoeff() - r1 * dx, y.maxCoeff(), dx);
|
||||
int nx = x_grid.size();
|
||||
@@ -1246,93 +1248,20 @@ bool G3PointAction::wolman()
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Default number of classes for associated histogram
|
||||
static const unsigned MAX_HISTOGRAM_SIZE = 512;
|
||||
|
||||
bool computeHistogram(const QVector<double>& data, QVector<double>& axis, QVector<double>& histogram)
|
||||
{
|
||||
double minData = *std::min_element(data.begin(), data.end());
|
||||
double maxData = *std::max_element(data.begin(), data.end());
|
||||
double range = maxData - minData;
|
||||
|
||||
if (range == 0 || data.size() == 0)
|
||||
{
|
||||
//can't build histogram of a flat field
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned count = data.size();
|
||||
unsigned numberOfBins = static_cast<unsigned>(ceil(sqrt(static_cast<double>(count))));
|
||||
// numberOfBins = std::max<unsigned>(std::min<unsigned>(numberOfBins, MAX_HISTOGRAM_SIZE), 4);
|
||||
numberOfBins = 10;
|
||||
|
||||
axis.resize(numberOfBins);
|
||||
for (int i = 0; i < numberOfBins; i++)
|
||||
{
|
||||
axis[i] = minData + i * range / numberOfBins;
|
||||
}
|
||||
|
||||
//reserve memory
|
||||
try
|
||||
{
|
||||
histogram.resize(numberOfBins);
|
||||
}
|
||||
catch (const std::bad_alloc&)
|
||||
{
|
||||
ccLog::Warning("[computeHistogram] Failed to allocate histogram!");
|
||||
}
|
||||
|
||||
std::fill(histogram.begin(), histogram.end(), 0);
|
||||
|
||||
//compute histogram
|
||||
ScalarType step = static_cast<ScalarType>(numberOfBins) / range;
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
{
|
||||
const ScalarType& val = data[i];
|
||||
|
||||
if (CCCoreLib::ScalarField::ValidValue(val))
|
||||
{
|
||||
unsigned bin = static_cast<unsigned>((val - minData) * step);
|
||||
++histogram[std::min(bin, numberOfBins - 1)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void showHistogram(const QVector<double>& data)
|
||||
{
|
||||
// QCustomPlot
|
||||
WolmanCustomPlot* anglesCustomPlot = new WolmanCustomPlot();
|
||||
QVector<double> axis;
|
||||
QVector<double> histogram;
|
||||
computeHistogram(data, axis, histogram);
|
||||
QCPBars *regen = new QCPBars(anglesCustomPlot->xAxis, anglesCustomPlot->yAxis);
|
||||
regen->setData(axis, histogram);
|
||||
regen->rescaleAxes();
|
||||
regen->setPen(QPen(QColor(0, 168, 140).lighter(130)));
|
||||
regen->setBrush(QColor(0, 168, 140));
|
||||
anglesCustomPlot->xAxis->setLabel("Azimut [°]");
|
||||
anglesCustomPlot->yAxis->setLabel("Counts");
|
||||
anglesCustomPlot->show();
|
||||
}
|
||||
|
||||
bool G3PointAction::angles()
|
||||
{
|
||||
if (m_grainsAsEllipsoids.isNull())
|
||||
if (!m_grainsAsEllipsoids)
|
||||
{
|
||||
ccLog::Error("[G3PointAction::angles] no ellipsoid, not possible to do angles analysis");
|
||||
return false;
|
||||
}
|
||||
|
||||
float delta = 1e32;
|
||||
int n_ellipsoids = m_grainsAsEllipsoids->m_rotationMatrix.size();
|
||||
size_t n_ellipsoids = m_grainsAsEllipsoids->m_rotationMatrix.size();
|
||||
QVector<double> granuloAngleMView(n_ellipsoids);
|
||||
QVector<double> granuloAngleXView(n_ellipsoids);
|
||||
|
||||
for (int i = 0; i < n_ellipsoids; i++)
|
||||
for (size_t i = 0; i < n_ellipsoids; i++)
|
||||
{
|
||||
float u, v, w;
|
||||
|
||||
@@ -1370,18 +1299,12 @@ bool G3PointAction::angles()
|
||||
}
|
||||
|
||||
// QCustomPlot
|
||||
WolmanCustomPlot* anglesCustomPlot = new WolmanCustomPlot();
|
||||
QVector<double> axis;
|
||||
QVector<double> histogram;
|
||||
computeHistogram(granuloAngleMView, axis, histogram);
|
||||
QCPBars *regen = new QCPBars(anglesCustomPlot->xAxis, anglesCustomPlot->yAxis);
|
||||
regen->setData(axis, histogram);
|
||||
regen->rescaleAxes();
|
||||
regen->setPen(QPen(QColor(0, 168, 140).lighter(130)));
|
||||
regen->setBrush(QColor(0, 168, 140));
|
||||
anglesCustomPlot->xAxis->setLabel("Azimut [°]");
|
||||
anglesCustomPlot->yAxis->setLabel("Counts");
|
||||
anglesCustomPlot->show();
|
||||
if (!s_g3PointPlots)
|
||||
s_g3PointPlots.reset(new G3PointPlots(m_cloud->getName()));
|
||||
int nbBins = m_dlg->getAnglesNbBins();
|
||||
s_g3PointPlots->addToTabWidget(new AnglesCustomPlot(granuloAngleMView, "Azimut", nbBins));
|
||||
s_g3PointPlots->addToTabWidget(new AnglesCustomPlot(granuloAngleXView, "Dip", nbBins));
|
||||
s_g3PointPlots->show();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2017,7 +1940,7 @@ void G3PointAction::showDlg()
|
||||
connect(m_dlg, &G3PointDialog::fit, s_g3PointAction.get(), &G3Point::G3PointAction::fit);
|
||||
connect(m_dlg, &G3PointDialog::exportResults, s_g3PointAction.get(), &G3Point::G3PointAction::exportResults);
|
||||
connect(m_dlg, &G3PointDialog::wolman, s_g3PointAction.get(), &G3Point::G3PointAction::wolman);
|
||||
connect(m_dlg, &G3PointDialog::angles, s_g3PointAction.get(), &G3Point::G3PointAction::angles);
|
||||
connect(m_dlg, &G3PointDialog::angles, s_g3PointAction.get(), &G3Point::G3PointAction::plots);
|
||||
|
||||
connect(m_dlg, &QDialog::finished, s_g3PointAction.get(), &G3Point::G3PointAction::clean);
|
||||
connect(m_dlg, &QDialog::finished, s_g3PointAction.get(), &G3Point::G3PointAction::resetDlg); // dialog is defined with Qt::WA_DeleteOnClose
|
||||
@@ -2116,7 +2039,11 @@ bool G3PointAction::setCloud(ccPointCloud *cloud)
|
||||
+ QString::number(nPointsInGrains) + "/" + QString::number(cloud->size())
|
||||
+ " points belonging to " + QString::number(newStacks.size()) + " grains");
|
||||
|
||||
std::cout << "[d] processNewStacks" << std::endl;
|
||||
|
||||
processNewStacks(newStacks, nPointsInGrains);
|
||||
|
||||
std::cout << "[e]" << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2125,7 +2052,6 @@ bool G3PointAction::setCloud(ccPointCloud *cloud)
|
||||
void G3PointAction::setKNN()
|
||||
{
|
||||
m_kNN = m_dlg->getkNN();
|
||||
std::cout << "kNN " << m_kNN << std::endl;
|
||||
}
|
||||
|
||||
void G3PointAction::createAction(ccMainAppInterface *appInterface)
|
||||
+29
-2
@@ -1,11 +1,11 @@
|
||||
#include "G3PointDialog.h"
|
||||
#include "ui_qG3PointDialog.h"
|
||||
#include "ui_G3PointDialog.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
G3PointDialog::G3PointDialog(QString cloudName, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::qG3PointDialog)
|
||||
, ui(new Ui::G3PointDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@@ -54,6 +54,12 @@ void G3PointDialog::readSettings()
|
||||
// max angle 1
|
||||
double maxAngle1 = settings.value("maxAngle1", 60).toDouble();
|
||||
this->ui->doubleSpinBoxRadiusFactor->setValue(maxAngle1);
|
||||
// wolmanNbIter
|
||||
int wolmanNbIter = settings.value("wolmanNbIter", 20).toInt();
|
||||
this->ui->spinBoxWolmanNbIter->setValue(wolmanNbIter);
|
||||
// anglesNbBins
|
||||
int anglesNbBins = settings.value("anglesNbBins", 10).toInt();
|
||||
this->ui->spinBoxAnglesNbBins->setValue(anglesNbBins);
|
||||
}
|
||||
|
||||
void G3PointDialog::writeSettings()
|
||||
@@ -67,6 +73,10 @@ void G3PointDialog::writeSettings()
|
||||
settings.setValue("radiusFactor", ui->doubleSpinBoxRadiusFactor->value());
|
||||
// max angle 1
|
||||
settings.setValue("maxAngle1", ui->doubleSpinBoxMaxAngle1->value());
|
||||
// wolmanNbIter
|
||||
settings.setValue("wolmanNbIter", ui->spinBoxWolmanNbIter->value());
|
||||
// anglesNbBins
|
||||
settings.setValue("anglesNbBins", ui->spinBoxAnglesNbBins->value());
|
||||
}
|
||||
|
||||
double G3PointDialog::getMaxAngle1()
|
||||
@@ -94,6 +104,23 @@ int G3PointDialog::getkNN()
|
||||
return this->ui->spinBoxkNN->value();
|
||||
}
|
||||
|
||||
int G3PointDialog::getWolmanNbIter()
|
||||
{
|
||||
return this->ui->spinBoxWolmanNbIter->value();
|
||||
}
|
||||
|
||||
int G3PointDialog::getAnglesNbBins()
|
||||
{
|
||||
if (this->ui->radioButtonAutoNbBins->isChecked())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->ui->spinBoxAnglesNbBins->value();
|
||||
}
|
||||
}
|
||||
|
||||
double G3PointDialog::getRadiusFactor()
|
||||
{
|
||||
return ui->doubleSpinBoxRadiusFactor->value();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "qG3PointDisclaimer.h"
|
||||
#include "ui_qG3PointDisclaimer.h"
|
||||
#include "G3PointDisclaimer.h"
|
||||
#include "ui_G3PointDisclaimer.h"
|
||||
|
||||
//qCC_plugins
|
||||
#include <ccMainAppInterface.h>
|
||||
@@ -7,9 +7,9 @@
|
||||
//Qt
|
||||
#include <QMainWindow>
|
||||
|
||||
bool qG3PointDisclaimer::s_disclaimerAccepted = false;
|
||||
bool G3PointDisclaimer::s_disclaimerAccepted = false;
|
||||
|
||||
qG3PointDisclaimer::qG3PointDisclaimer(QWidget *parent)
|
||||
G3PointDisclaimer::G3PointDisclaimer(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::G3PointDisclaimer)
|
||||
{
|
||||
@@ -34,17 +34,17 @@ qG3PointDisclaimer::qG3PointDisclaimer(QWidget *parent)
|
||||
ui->labelCompilationInformation->setText(compilationInfo);
|
||||
}
|
||||
|
||||
qG3PointDisclaimer::~qG3PointDisclaimer()
|
||||
G3PointDisclaimer::~G3PointDisclaimer()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool qG3PointDisclaimer::show(ccMainAppInterface *app)
|
||||
bool G3PointDisclaimer::show(ccMainAppInterface *app)
|
||||
{
|
||||
if ( !s_disclaimerAccepted )
|
||||
{
|
||||
//if the user "cancels" it, then he refuses the disclaimer
|
||||
s_disclaimerAccepted = qG3PointDisclaimer(app ? app->getMainWindow() : 0).exec();
|
||||
s_disclaimerAccepted = G3PointDisclaimer(app ? app->getMainWindow() : 0).exec();
|
||||
}
|
||||
|
||||
return s_disclaimerAccepted;
|
||||
@@ -0,0 +1,166 @@
|
||||
#include "G3PointPlots.h"
|
||||
#include "ui_G3PointPlots.h"
|
||||
|
||||
// CCPluginAPI
|
||||
#include <ccPersistentSettings.h>
|
||||
|
||||
/// qCC_db
|
||||
#include <ccFileUtils.h>
|
||||
|
||||
// qcc_io
|
||||
#include <ImageFileFilter.h>
|
||||
|
||||
#include <QTextStream>
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <AnglesCustomPlot.h>
|
||||
|
||||
#include <WolmanCustomPlot.h>
|
||||
|
||||
G3PointPlots::G3PointPlots(QString title, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::G3PointPlots)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
readSettings();
|
||||
|
||||
setWindowTitle(title);
|
||||
|
||||
connect(this->ui->exportCSVToolButton, &QToolButton::clicked, this, &G3PointPlots::onExportToCSV);
|
||||
connect(this->ui->exportImage, &QToolButton::clicked, this, &G3PointPlots::onExportToImage);
|
||||
}
|
||||
|
||||
G3PointPlots::~G3PointPlots()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void G3PointPlots::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
QSettings settings("OSERen", "qG3Point");
|
||||
settings.setValue("G3PointPlots/geometry", saveGeometry());
|
||||
// settings.setValue("windowState", saveState());
|
||||
QWidget::closeEvent(event);
|
||||
}
|
||||
|
||||
void G3PointPlots::readSettings()
|
||||
{
|
||||
QSettings settings("OSERen", "qG3Point");
|
||||
restoreGeometry(settings.value("G3PointPlots/geometry").toByteArray());
|
||||
}
|
||||
|
||||
void G3PointPlots::addToTabWidget(QWidget* widget)
|
||||
{
|
||||
this->ui->tabWidget->addTab(widget, widget->windowTitle());
|
||||
this->ui->tabWidget->setCurrentWidget(widget);
|
||||
}
|
||||
|
||||
template<typename SharedDataContainer>
|
||||
bool G3PointPlots::exportToCSV(QString filename, SharedDataContainer container) const
|
||||
{
|
||||
QFile file(filename);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Text))
|
||||
{
|
||||
ccLog::Warning(QString("[SF/SF] Failed to save plot to file '%1'").arg(filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextStream stream(&file);
|
||||
stream.setRealNumberPrecision(12);
|
||||
stream.setRealNumberNotation(QTextStream::FixedNotation);
|
||||
|
||||
//header
|
||||
stream << "angle [°], counts" << endl;
|
||||
|
||||
//data
|
||||
{
|
||||
for (auto item : *container)
|
||||
{
|
||||
stream << item.key << " " << item.value << endl;
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
ccLog::Print(QString("[SF/SF] File '%1' saved").arg(filename));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef QSharedPointer<QCPBarsDataContainer> SharedBarsDataContainer;
|
||||
typedef QSharedPointer<QCPGraphDataContainer> SharedGraphDataContainer;
|
||||
|
||||
void G3PointPlots::onExportToCSV()
|
||||
{
|
||||
// get current tab widget
|
||||
QWidget* currentWidget = this->ui->tabWidget->currentWidget();
|
||||
|
||||
//persistent settings
|
||||
QSettings settings;
|
||||
settings.beginGroup(ccPS::SaveFile());
|
||||
QString currentPath = settings.value(ccPS::CurrentPath(), ccFileUtils::defaultDocPath()).toString();
|
||||
|
||||
currentPath += QString("/") + currentWidget->windowTitle() + ".csv";
|
||||
|
||||
//ask for a filename
|
||||
QString filename = QFileDialog::getSaveFileName(this, "Select output file", currentPath, "*.csv");
|
||||
if (filename.isEmpty())
|
||||
{
|
||||
//process cancelled by user
|
||||
return;
|
||||
}
|
||||
|
||||
//save last saving location
|
||||
settings.setValue(ccPS::CurrentPath(), QFileInfo(filename).absolutePath());
|
||||
settings.endGroup();
|
||||
|
||||
if (currentWidget->property("TypeOfCustomPlot").toString() == "AnglesCustomPlot")
|
||||
{
|
||||
exportToCSV<SharedBarsDataContainer>(filename,
|
||||
static_cast<AnglesCustomPlot*>(currentWidget)->dataContainer());
|
||||
}
|
||||
else if (currentWidget->property("TypeOfCustomPlot").toString() == "WolmanCustomPlot")
|
||||
{
|
||||
exportToCSV<SharedGraphDataContainer>(filename,
|
||||
static_cast<WolmanCustomPlot*>(currentWidget)->dataContainer());
|
||||
}
|
||||
}
|
||||
|
||||
void G3PointPlots::onExportToImage()
|
||||
{
|
||||
QWidget* currentWidget = this->ui->tabWidget->currentWidget();
|
||||
|
||||
//persistent settings
|
||||
QSettings settings;
|
||||
settings.beginGroup(ccPS::SaveFile());
|
||||
QString currentPath = settings.value(ccPS::CurrentPath(), ccFileUtils::defaultDocPath()).toString();
|
||||
|
||||
QString outputFilename = ImageFileFilter::GetSaveFilename("Select output file",
|
||||
currentWidget->windowTitle(),
|
||||
currentPath,
|
||||
this);
|
||||
|
||||
if (outputFilename.isEmpty())
|
||||
{
|
||||
//process cancelled by user (or error)
|
||||
return;
|
||||
}
|
||||
|
||||
//save current export path to persistent settings
|
||||
settings.setValue(ccPS::CurrentPath(), QFileInfo(outputFilename).absolutePath());
|
||||
settings.endGroup();
|
||||
|
||||
//save the widget as an image file
|
||||
QPixmap image = currentWidget->grab();
|
||||
if (image.save(outputFilename))
|
||||
{
|
||||
ccLog::Print(QString("[SF/SF] Image '%1' successfully saved").arg(outputFilename));
|
||||
}
|
||||
else
|
||||
{
|
||||
ccLog::Error(QString("Failed to save file '%1'").arg(outputFilename));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <ActionA.h>
|
||||
#include <G3PointAction.h>
|
||||
|
||||
// from GeometricTools/GTE
|
||||
// #include <Mathematics/DistPointHyperellipsoid.h>
|
||||
@@ -30,6 +30,8 @@ GrainsAsEllipsoids::GrainsAsEllipsoids(ccMainAppInterface *app)
|
||||
setShaderPath();
|
||||
}
|
||||
|
||||
GrainsAsEllipsoids::~GrainsAsEllipsoids(){}
|
||||
|
||||
GrainsAsEllipsoids::GrainsAsEllipsoids(ccPointCloud *cloud, ccMainAppInterface *app, const std::vector<std::vector<int> >& stacks, const RGBAColorsTableType& colors)
|
||||
: m_cloud(cloud)
|
||||
, m_app(app)
|
||||
@@ -237,7 +239,9 @@ bool GrainsAsEllipsoids::exportResultsAsCloud()
|
||||
cloud->showColors(true);
|
||||
cloud->setPointSize(9);
|
||||
|
||||
m_cloud->getParent()->addChild(cloud, ccHObject::DP_PARENT_OF_OTHER, 0);
|
||||
// m_cloud->getParent()->addChild(cloud, ccHObject::DP_PARENT_OF_OTHER, 0);
|
||||
// m_app->addToDB(cloud);
|
||||
m_cloud->addChild(cloud);
|
||||
m_app->addToDB(cloud);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
#include "WolmanCustomPlot.h"
|
||||
#include "ui_WolmanCustomPlot.h"
|
||||
|
||||
WolmanCustomPlot::WolmanCustomPlot(QWidget *parent):
|
||||
WolmanCustomPlot::WolmanCustomPlot(const Eigen::ArrayXf &d_sample):
|
||||
ui(new Ui::WolmanCustomPlot)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
setProperty("TypeOfCustomPlot", "WolmanCustomPlot");
|
||||
|
||||
WolmanCustomPlot::~WolmanCustomPlot()
|
||||
{
|
||||
delete ui;
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowTitle("Wolman");
|
||||
|
||||
m_graph = this->ui->customPlot->addGraph();
|
||||
QVector<double> x_data(d_sample.size());
|
||||
QVector<double> y_data(d_sample.size());
|
||||
for (int k = 0; k < d_sample.size(); k++)
|
||||
{
|
||||
x_data[k] = d_sample(k);
|
||||
y_data[k] = (static_cast<double>(k)) / static_cast<double>(d_sample.size());
|
||||
}
|
||||
std::sort(x_data.begin(), x_data.end());
|
||||
m_graph->setData(x_data, y_data);
|
||||
m_graph->rescaleAxes();
|
||||
// give the axes some labels:
|
||||
this->ui->customPlot->xAxis->setScaleType(QCPAxis::stLogarithmic);
|
||||
this->ui->customPlot->xAxis->setLabel("Diameter [mm]");
|
||||
this->ui->customPlot->yAxis->setLabel("CDF");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AnglesCustomPlot</class>
|
||||
<widget class="QWidget" name="AnglesCustomPlot">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
target_sources( ${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}/qG3PointDialog.ui
|
||||
${CMAKE_CURRENT_LIST_DIR}/qG3PointDisclaimer.ui
|
||||
${CMAKE_CURRENT_LIST_DIR}/WolmanCustomPlot.ui
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointDialog.ui
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointDisclaimer.ui
|
||||
${CMAKE_CURRENT_LIST_DIR}/AnglesCustomPlot.ui
|
||||
${CMAKE_CURRENT_LIST_DIR}/G3PointPlots.ui
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>qG3PointDialog</class>
|
||||
<widget class="QDialog" name="qG3PointDialog">
|
||||
<class>G3PointDialog</class>
|
||||
<widget class="QDialog" name="G3PointDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>357</width>
|
||||
<width>384</width>
|
||||
<height>608</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -347,24 +347,95 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonExportResults">
|
||||
<property name="text">
|
||||
<string>Export results</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonWolman">
|
||||
<property name="text">
|
||||
<string>Wolman</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonAngles">
|
||||
<property name="text">
|
||||
<string>Angles</string>
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="title">
|
||||
<string>Outputs</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="1,0,0,0,0,0">
|
||||
<item row="3" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="pushButtonExportResults">
|
||||
<property name="text">
|
||||
<string>Export results as a cloud</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="pushButtonAngles">
|
||||
<property name="text">
|
||||
<string>Angles</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="font">
|
||||
<font>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Nb bins:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QRadioButton" name="radioButtonAutoNbBins">
|
||||
<property name="text">
|
||||
<string>Auto</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QRadioButton" name="radioButtonFixNbBins">
|
||||
<property name="text">
|
||||
<string>Fix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<widget class="QSpinBox" name="spinBoxAnglesNbBins">
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>512</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QSpinBox" name="spinBoxWolmanNbIter">
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Nb iterations</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<widget class="QPushButton" name="pushButtonWolman">
|
||||
<property name="text">
|
||||
<string>Wolman</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>G3PointPlots</class>
|
||||
<widget class="QWidget" name="G3PointPlots">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>751</width>
|
||||
<height>641</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>G3Point plots</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" rowstretch="1,0" columnstretch="1,0">
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="exportCSVToolButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../qG3POINT.qrc">
|
||||
<normaloff>:/CC/plugin/G3PointPlugin/images/smallCSVFile.png</normaloff>:/CC/plugin/G3PointPlugin/images/smallCSVFile.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="exportImage">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../qG3POINT.qrc">
|
||||
<normaloff>:/CC/plugin/G3PointPlugin/images/dbImageSymbol.png</normaloff>:/CC/plugin/G3PointPlugin/images/dbImageSymbol.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>560</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../qG3POINT.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -13,7 +13,20 @@
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" rowstretch="1">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCustomPlot" name="customPlot" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QCustomPlot</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qcustomplot.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
Reference in New Issue
Block a user