Newer
Older
// ************************************************************************************************
// BornAgain: simulate and fit reflection and scattering
//! @file GUI/Views/MaterialEditor/MaterialItemUtils.cpp
//! @brief Implements class MaterialItemUtils
//! @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/Views/MaterialEditor/MaterialItemUtils.h"
#include "GUI/Models/ComboProperty.h"
#include "GUI/Models/Error.h"
#include "GUI/Models/LayerItem.h"
#include "GUI/Models/MaterialDataItems.h"
#include "GUI/Models/MaterialItemContainer.h"
#include "GUI/Models/MaterialModel.h"
#include "GUI/Models/MesoCrystalItem.h"
#include "GUI/Models/ParticleCompositionItem.h"
#include "GUI/Models/ParticleCoreShellItem.h"
#include "GUI/Models/ParticleItem.h"
#include "GUI/Models/ParticleLayoutItem.h"
#include "GUI/Views/MaterialEditor/MaterialEditorDialog.h"
#include "GUI/Views/SampleDesigner/DesignerHelper.h"
#include "GUI/mainwindow/AppSvc.h"
#include "GUI/mainwindow/mainwindow.h"
#include <QColorDialog>
std::map<QString, QString> get_tag_map()
{
std::map<QString, QString> result = {

Wuttke, Joachim
committed
{"ParticleComposition", ParticleCompositionItem::T_PARTICLES},
{"ParticleLayout", ParticleLayoutItem::T_PARTICLES},
{"MesoCrystal", MesoCrystalItem::T_BASIS_PARTICLE}};
QColor MaterialItemUtils::suggestMaterialColor(const QString& name)
{
if (name.contains("Vacuum")) {
return QColor(179, 242, 255);
} else if (name.contains("Substrate")) {
return QColor(205, 102, 0);
} else if (name.contains("Default")) {
return QColor(146, 198, 255);
return DesignerHelper::getRandomColor();
}
ExternalProperty MaterialItemUtils::defaultMaterialProperty()
{
Pospelov, Gennady
committed
if (!AppSvc::materialModel())
return ExternalProperty();
auto materials = AppSvc::materialModel()->topItems<MaterialItem>();
return materials.isEmpty() ? ExternalProperty()
: MaterialItemUtils::materialProperty(*materials.front());
MaterialItemUtils::createDomainMaterial(const ExternalProperty& material_property)
{
MaterialItem* materialItem = findMaterial(material_property);
return materialItem->createMaterial();
}
std::unique_ptr<Material>
MaterialItemUtils::createDomainMaterial(const ExternalProperty& material_property,
const MaterialItemContainer& container)
{
const MaterialItem* material_item = container.findMaterialById(material_property.identifier());
if (!material_item)
throw Error("MaterialUtils::createDomainMaterial() -> Error. Can't find "
"material with name '"
+ material_property.text() + "'.");
return material_item->createMaterial();
}
MaterialItem* MaterialItemUtils::findMaterial(const ExternalProperty& material_property)
{
throw Error("MaterialItemUtils::findMaterial() -> Error. "
"Attempt to access non-existing material model");
auto material = AppSvc::materialModel()->materialFromIdentifier(material_property.identifier());
throw Error("MaterialUtils::findMaterial() -> Error. Can't find "
"material with name '"
+ material_property.text() + "'.");
//! Returns material tag for given item. Returns empty string, if item doesn't have materials.
QString MaterialItemUtils::materialTag(const SessionItem& item)
{
QString result;

Wuttke, Joachim
committed
if (item.modelType() == "Particle") {
result = ParticleItem::P_MATERIAL;

Wuttke, Joachim
committed
} else if (item.modelType() == "Layer") {
result = LayerItem::P_MATERIAL;
}
return result;
}
Pospelov, Gennady
committed
//! Returns list of model types which contains registered MaterialProperty.
QStringList MaterialItemUtils::materialRelatedModelTypes()
{

Wuttke, Joachim
committed
return {"Particle", "Layer"};
Pospelov, Gennady
committed
}
//! Constructs material property for given material.
Pospelov, Gennady
committed
ExternalProperty MaterialItemUtils::materialProperty(const MaterialItem& materialItem)
result.setIdentifier(materialItem.identifier());
result.setText(materialItem.itemName());
return result;
}
ExternalProperty MaterialItemUtils::colorProperty(const QColor& color)
{
ExternalProperty result;
result.setColor(color);
result.setText(QString("[%1, %2, %3] (%4)")
.arg(color.red())
.arg(color.green())
.arg(color.blue())
.arg(color.alpha()));
return result;
}
ExternalProperty MaterialItemUtils::selectMaterialProperty(const ExternalProperty& previous)
{
MaterialEditorDialog dialog(AppSvc::materialModel(), MainWindow::instance());
dialog.setMaterialProperty(previous);
return dialog.selectedMaterialProperty();
return ExternalProperty();
Pospelov, Gennady
committed
ExternalProperty MaterialItemUtils::selectColorProperty(const ExternalProperty& previous)
{
ExternalProperty result;
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
auto oldColor = previous.color();
auto newColor = QColorDialog::getColor(oldColor);
if (oldColor != newColor)
result = MaterialItemUtils::colorProperty(newColor);
#else
bool ok = false;
QRgb oldRgba = previous.color().rgba();
QRgb newRgba = QColorDialog::getRgba(oldRgba, &ok, nullptr);
if (ok && newRgba != oldRgba)
result = MaterialItemUtils::colorProperty(QColor::fromRgba(newRgba));
#endif
return result;
}
QVector<SessionItem*> MaterialItemUtils::materialPropertyItems(SessionItem* item)
{
static const std::map<QString, QString> tag_map = get_tag_map();
QVector<SessionItem*> materials;
QList<SessionItem*> particle_holders{item};
while (!particle_holders.isEmpty()) {
auto item = particle_holders.takeFirst();
if (!item)
continue;
const QString model_type = item->modelType();
auto iter = tag_map.find(model_type);
if (iter != tag_map.end()) {
particle_holders.append(QList<SessionItem*>::fromVector(item->getItems(iter->second)));
continue;
}

Wuttke, Joachim
committed
if (model_type == "Particle")
materials.append(static_cast<ParticleItem*>(item)->materialPropertyItems());

Wuttke, Joachim
committed
else if (model_type == "ParticleCoreShell")
materials.append(static_cast<ParticleCoreShellItem*>(item)->materialPropertyItems());
else
"Error in MaterialItemUtils::materialProperties: cannot handle passed model type '"
+ model_type + "'");
}
return materials;
}