Skip to content
Snippets Groups Projects
Commit 817fe983 authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

merge MaskResultsPresenter into MaskEditorCanvas

parent 95be2966
No related branches found
No related tags found
1 merge request!2269restore display of masked pixels (lightbulb button)
Pipeline #125023 passed
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/Model/Data/MaskResultsPresenter.cpp
//! @brief Implements class MaskResultsPresenter.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#include "GUI/Model/Data/MaskResultsPresenter.h"
#include "Device/Data/Datafield.h"
#include "Device/Mask/IShape2D.h"
#include "Device/Mask/MaskStack.h"
#include "GUI/Model/Data/Data2DItem.h"
#include "GUI/Model/Mask/MaskItems.h"
#include "GUI/Model/Mask/MaskList.h"
namespace {
//! Constructs Datafield which contains original intensity data except masked areas,
//! and areas outside of ROI, where bin content is set to zero.
Datafield* createMaskPresentation(Data2DItem* data2DItem)
{
// Requesting mask information
std::unique_ptr<IShape2D> roi;
Datafield* result = data2DItem->c_field()->clone();
MaskStack detectorMask;
const QVector<const MaskItem*> maskItems = data2DItem->maskContainerItem()->maskItems();
for (auto maskIter = maskItems.rbegin(); maskIter != maskItems.rend(); maskIter++)
if ((*maskIter)->isVisible()) {
if (auto* roiItem = dynamic_cast<const RegionOfInterestItem*>((*maskIter)))
roi = roiItem->createShape();
else {
std::unique_ptr<IShape2D> shape((*maskIter)->createShape());
detectorMask.maskToStack(*shape, (*maskIter)->maskValue(), false);
}
}
// ROI mask has to be the last one, it can not be "unmasked" by other shapes
if (roi)
detectorMask.maskToStack(*roi, true, false);
if (!detectorMask.hasMasks())
return nullptr;
for (size_t i = 0; i < result->size(); ++i)
if (detectorMask.isMasked(i, result->frame()))
(*result)[i] = 0;
return result;
}
} // namespace
MaskResultsPresenter::MaskResultsPresenter() = default;
MaskResultsPresenter::~MaskResultsPresenter() = default;
void MaskResultsPresenter::updateMaskResults(Data2DItem* data2DItem)
{
m_data2DItem = data2DItem;
}
void MaskResultsPresenter::updatePresenter(bool pixelized)
{
ASSERT(m_data2DItem);
if (pixelized) {
if (Datafield* maskedData = ::createMaskPresentation(m_data2DItem)) {
// store data backup
m_backup_data.reset(m_data2DItem->c_field()->clone());
m_backup_interpolated = m_data2DItem->isInterpolated();
m_data2DItem->setDatafield(*maskedData);
m_data2DItem->setInterpolated(false);
} else {
m_backup_data.reset();
}
} else {
if (m_backup_data) {
m_data2DItem->setDatafield(*m_backup_data);
m_data2DItem->setInterpolated(m_backup_interpolated);
}
}
}
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/Model/Data/MaskResultsPresenter.h
//! @brief Defines class MaskResultsPresenter.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#ifndef BORNAGAIN_GUI_MODEL_DATA_MASKRESULTSPRESENTER_H
#define BORNAGAIN_GUI_MODEL_DATA_MASKRESULTSPRESENTER_H
#include <memory>
class Data2DItem;
class Datafield;
//! Updates bin values inside IntensityData to display current mask state.
class MaskResultsPresenter {
public:
MaskResultsPresenter();
~MaskResultsPresenter();
void updateMaskResults(Data2DItem* data2DItem);
void updatePresenter(bool pixelized);
private:
Data2DItem* m_data2DItem;
std::unique_ptr<Datafield> m_backup_data;
bool m_backup_interpolated = false;
};
#endif // BORNAGAIN_GUI_MODEL_DATA_MASKRESULTSPRESENTER_H
...@@ -13,8 +13,10 @@ ...@@ -13,8 +13,10 @@
// ************************************************************************************************ // ************************************************************************************************
#include "GUI/View/Canvas/MaskEditorCanvas.h" #include "GUI/View/Canvas/MaskEditorCanvas.h"
#include "Device/Data/Datafield.h"
#include "Device/Mask/IShape2D.h"
#include "Device/Mask/MaskStack.h"
#include "GUI/Model/Data/Data2DItem.h" #include "GUI/Model/Data/Data2DItem.h"
#include "GUI/Model/Data/MaskResultsPresenter.h"
#include "GUI/Model/Mask/MaskItems.h" #include "GUI/Model/Mask/MaskItems.h"
#include "GUI/Model/Mask/MaskList.h" #include "GUI/Model/Mask/MaskList.h"
#include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Model/Project/ProjectDocument.h"
...@@ -25,13 +27,51 @@ ...@@ -25,13 +27,51 @@
#include "GUI/View/Scene/MaskGraphicsView.h" #include "GUI/View/Scene/MaskGraphicsView.h"
#include <QVBoxLayout> #include <QVBoxLayout>
namespace {
//! Constructs Datafield which contains original intensity data except masked areas,
//! and areas outside of ROI, where bin content is set to zero.
Datafield* createMaskPresentation(Data2DItem* data2DItem)
{
// Requesting mask information
std::unique_ptr<IShape2D> roi;
Datafield* result = data2DItem->c_field()->clone();
MaskStack detectorMask;
const QVector<const MaskItem*> maskItems = data2DItem->maskContainerItem()->maskItems();
for (auto maskIter = maskItems.rbegin(); maskIter != maskItems.rend(); maskIter++)
if ((*maskIter)->isVisible()) {
if (auto* roiItem = dynamic_cast<const RegionOfInterestItem*>((*maskIter)))
roi = roiItem->createShape();
else {
std::unique_ptr<IShape2D> shape((*maskIter)->createShape());
detectorMask.maskToStack(*shape, (*maskIter)->maskValue(), false);
}
}
// ROI mask has to be the last one, it can not be "unmasked" by other shapes
if (roi)
detectorMask.maskToStack(*roi, true, false);
if (!detectorMask.hasMasks())
return nullptr;
for (size_t i = 0; i < result->size(); ++i)
if (detectorMask.isMasked(i, result->frame()))
(*result)[i] = 0;
return result;
}
} // namespace
MaskEditorCanvas::MaskEditorCanvas(QWidget* parent) MaskEditorCanvas::MaskEditorCanvas(QWidget* parent)
: QWidget(parent) : QWidget(parent)
, m_scene(new MaskGraphicsScene) , m_scene(new MaskGraphicsScene)
, m_view(new MaskGraphicsView(m_scene)) , m_view(new MaskGraphicsView(m_scene))
, m_data2DItem(nullptr) , m_data2DItem(nullptr)
, m_statusLabel(new PlotStatusLabel(nullptr, this)) , m_statusLabel(new PlotStatusLabel(nullptr, this))
, m_resultsPresenter(new MaskResultsPresenter)
{ {
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
...@@ -48,12 +88,12 @@ MaskEditorCanvas::MaskEditorCanvas(QWidget* parent) ...@@ -48,12 +88,12 @@ MaskEditorCanvas::MaskEditorCanvas(QWidget* parent)
&MaskEditorCanvas::deleteSelectedRequest); &MaskEditorCanvas::deleteSelectedRequest);
} }
MaskEditorCanvas::~MaskEditorCanvas() = default;
void MaskEditorCanvas::updateMaskCanvas(Data2DItem* data2DItem, QItemSelectionModel* selModel) void MaskEditorCanvas::updateMaskCanvas(Data2DItem* data2DItem, QItemSelectionModel* selModel)
{ {
m_data2DItem = data2DItem; m_data2DItem = data2DItem;
m_resultsPresenter->updateMaskResults(data2DItem);
m_scene->updateSize(m_view->size()); m_scene->updateSize(m_view->size());
m_scene->associateItems(data2DItem, data2DItem->getOrCreateMaskModel(), selModel); m_scene->associateItems(data2DItem, data2DItem->getOrCreateMaskModel(), selModel);
...@@ -70,7 +110,27 @@ void MaskEditorCanvas::resetMaskCanvas() ...@@ -70,7 +110,27 @@ void MaskEditorCanvas::resetMaskCanvas()
void MaskEditorCanvas::onPresentationChange(bool pixelized) void MaskEditorCanvas::onPresentationChange(bool pixelized)
{ {
m_scene->clearSelection(); // important to avoid crash (unsubscribe while calling subscribers) m_scene->clearSelection(); // important to avoid crash (unsubscribe while calling subscribers)
m_resultsPresenter->updatePresenter(pixelized);
ASSERT(m_data2DItem);
if (pixelized) {
if (Datafield* maskedData = ::createMaskPresentation(m_data2DItem)) {
// store data backup
m_backup_data.reset(m_data2DItem->c_field()->clone());
m_backup_interpolated = m_data2DItem->isInterpolated();
m_data2DItem->setDatafield(*maskedData);
m_data2DItem->setInterpolated(false);
} else {
m_backup_data.reset();
}
} else {
if (m_backup_data) {
m_data2DItem->setDatafield(*m_backup_data);
m_data2DItem->setInterpolated(m_backup_interpolated);
}
}
if (auto* container = m_data2DItem->maskContainerItem()) if (auto* container = m_data2DItem->maskContainerItem())
for (MaskItem* mask : container->modifiableMaskItems()) for (MaskItem* mask : container->modifiableMaskItems())
......
...@@ -19,11 +19,12 @@ ...@@ -19,11 +19,12 @@
#include <QItemSelectionModel> #include <QItemSelectionModel>
#include <QModelIndex> #include <QModelIndex>
#include <QWidget> #include <QWidget>
#include <memory>
class Data2DItem; class Data2DItem;
class Datafield;
class MaskGraphicsScene; class MaskGraphicsScene;
class MaskGraphicsView; class MaskGraphicsView;
class MaskResultsPresenter;
class PlotStatusLabel; class PlotStatusLabel;
//! Painting widget for MaskEditor, contains graphics scene and graphics view //! Painting widget for MaskEditor, contains graphics scene and graphics view
...@@ -32,6 +33,7 @@ class MaskEditorCanvas : public QWidget { ...@@ -32,6 +33,7 @@ class MaskEditorCanvas : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
MaskEditorCanvas(QWidget* parent = nullptr); MaskEditorCanvas(QWidget* parent = nullptr);
~MaskEditorCanvas();
void updateMaskCanvas(Data2DItem* data2DItem, QItemSelectionModel* selModel); void updateMaskCanvas(Data2DItem* data2DItem, QItemSelectionModel* selModel);
...@@ -55,7 +57,8 @@ private: ...@@ -55,7 +57,8 @@ private:
MaskGraphicsView* m_view; MaskGraphicsView* m_view;
Data2DItem* m_data2DItem; Data2DItem* m_data2DItem;
PlotStatusLabel* m_statusLabel; PlotStatusLabel* m_statusLabel;
MaskResultsPresenter* m_resultsPresenter; std::unique_ptr<Datafield> m_backup_data;
bool m_backup_interpolated = false;
}; };
#endif // BORNAGAIN_GUI_VIEW_CANVAS_MASKEDITORCANVAS_H #endif // BORNAGAIN_GUI_VIEW_CANVAS_MASKEDITORCANVAS_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment