BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
MaterialItems.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/Model/Sample/MaterialItems.cpp
6 //! @brief Implements class MaterialItems
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
16 #include "Base/Util/Assert.h"
19 #include <QColor>
20 #include <QUuid>
21 #include <random>
22 
23 namespace {
24 
25 QColor suggestMaterialColor(const QString& name)
26 {
27  if (name.contains("Vacuum"))
28  return QColor(179, 242, 255);
29  if (name.contains("Substrate"))
30  return QColor(205, 102, 0);
31  if (name.contains("Default"))
32  return QColor(Qt::green);
33  if (name.contains("Particle"))
34  return QColor(146, 198, 255);
35 
36  // return a random color
37  static std::random_device r;
38  std::default_random_engine re(r());
39  std::uniform_int_distribution<int> ru(0, 255);
40 
41  return QColor(ru(re), ru(re), ru(re));
42 }
43 
44 } // namespace
45 
46 
48  : QObject(parent)
49 {
50 }
51 
53 {
54  clear();
55 }
56 
58 {
59  qDeleteAll(m_materialItems);
60  m_materialItems.clear();
61 }
62 
64 {
65  addMaterial(material, true);
66 }
67 
68 void MaterialItems::addMaterial(MaterialItem* material, bool signalAdding)
69 {
70  ASSERT(material);
71  material->disconnect(this);
72  m_materialItems << material;
73  connect(material, &MaterialItem::dataChanged, this, [=] { emit materialChanged(material); });
74 
75  if (signalAdding)
77 }
78 
80 {
81  auto* result = new MaterialItems();
82 
83  for (const auto* m : m_materialItems)
84  result->addMaterial(new MaterialItem(*m));
85 
86  return result;
87 }
88 
89 MaterialItem* MaterialItems::addRefractiveMaterial(const QString& name, double delta, double beta)
90 {
91  auto* materialItem = new MaterialItem();
92  materialItem->setMatItemName(name);
93  materialItem->setColor(suggestMaterialColor(name));
94  materialItem->setRefractiveIndex(delta, beta);
95  addMaterial(materialItem);
96 
97  return materialItem;
98 }
99 
100 MaterialItem* MaterialItems::addSLDMaterial(const QString& name, double sld, double abs_term)
101 {
102  auto* materialItem = new MaterialItem();
103  materialItem->setMatItemName(name);
104  materialItem->setColor(suggestMaterialColor(name));
105  materialItem->setScatteringLengthDensity(complex_t(sld, abs_term));
106  addMaterial(materialItem);
107 
108  return materialItem;
109 }
110 
112 {
113  for (auto* materialItem : m_materialItems)
114  if (materialItem->matItemName() == name)
115  return materialItem;
116 
117  return nullptr;
118 }
119 
120 MaterialItem* MaterialItems::materialFromIdentifier(const QString& identifier) const
121 {
122  for (auto* materialItem : m_materialItems)
123  if (materialItem->identifier() == identifier)
124  return materialItem;
125 
126  return nullptr;
127 }
128 
130 {
131  auto* newMaterial = new MaterialItem(material);
132  newMaterial->createNewIdentifier();
133  newMaterial->setMatItemName(material.matItemName() + " (copy)");
134  addMaterial(newMaterial);
135 
136  return newMaterial;
137 }
138 
139 const QVector<MaterialItem*>& MaterialItems::materialItems() const
140 {
141  return m_materialItems;
142 }
143 
145 {
146  ASSERT(!materialItems().isEmpty());
147  return materialItems().front();
148 }
149 
150 void MaterialItems::removeMaterial(const QString& identifier)
151 {
153 }
154 
156 {
157  m_materialItems.removeAll(materialItem);
158  delete materialItem;
159  emit materialAddedOrRemoved();
160 }
161 
163 {
164  if (s.xmlReader())
165  clear();
166  s.assertVersion(0);
167  Serialize::rwVector(s, "MaterialItems", m_materialItems);
168 }
169 
171 {
172  // update existing to new contents (do not delete and recreate to keep references valid)
173  for (auto* destItem : m_materialItems)
174  if (auto* fromItem = from.materialFromIdentifier(destItem->identifier()))
175  destItem->updateFrom(*fromItem);
176 
177  bool anyAddedOrRemoved = false;
178 
179  // remove non-existing
180  auto* iter = m_materialItems.begin();
181  while (iter != m_materialItems.end())
182  if (!from.materialFromIdentifier((*iter)->identifier())) {
183  delete *iter;
184  iter = m_materialItems.erase(iter);
185  anyAddedOrRemoved = true;
186  } else
187  iter++;
188 
189  // copy new ones
190  for (const auto* m : from.materialItems())
191  if (!materialFromIdentifier(m->identifier())) {
192  addMaterial(new MaterialItem(*m), false);
193  anyAddedOrRemoved = true;
194  }
195 
196  // copy order
197  QVector<MaterialItem*> tmp;
198  for (const auto* m : from.materialItems())
199  tmp << materialFromIdentifier(m->identifier());
200  m_materialItems = tmp;
201 
202  if (anyAddedOrRemoved)
203  emit materialAddedOrRemoved();
204 }
205 
206 bool MaterialItems::operator==(const MaterialItems& other) const
207 {
208  if (m_materialItems.size() != other.m_materialItems.size())
209  return false;
210 
211  for (int i = 0; i < m_materialItems.size(); i++)
212  if (*m_materialItems[i] != *other.m_materialItems[i])
213  return false;
214 
215  return true;
216 }
217 
218 bool MaterialItems::operator!=(const MaterialItems& other) const
219 {
220  return !operator==(other);
221 }
Defines class MaterialItem.
Defines class MaterialItems.
Defines class Streamer.
@ other
The unit has no enum value defined in here (e.g. when defined as an explicit string)
QString matItemName() const
void dataChanged() const
void addMaterial(MaterialItem *material)
Add the material and take ownership of it.
MaterialItem * addRefractiveMaterial(const QString &name, double delta, double beta)
MaterialItem * materialFromIdentifier(const QString &identifier) const
MaterialItem * defaultMaterial() const
void materialAddedOrRemoved()
void initFrom(const MaterialItems &from)
Copies the complete content, emitting signals for existing and changed materials.
MaterialItem * addSLDMaterial(const QString &name, double sld, double abs_term)
QVector< MaterialItem * > m_materialItems
all materials (owned by this class)
Definition: MaterialItems.h:76
void removeMaterial(const QString &identifier)
MaterialItems(QObject *parent=nullptr)
MaterialItems * createCopy() const
MaterialItem * insertCopy(const MaterialItem &material)
Inserts a copy of the given material and returns the newly inserted item.
bool operator==(const MaterialItems &other) const
Compares for complete equality (same material identifiers, same order of materials,...
const QVector< MaterialItem * > & materialItems() const
void materialChanged(MaterialItem *materialItem)
MaterialItem * materialFromName(const QString &name) const
bool operator!=(const MaterialItems &other) const
void serialize(Streamer &s)
Supports serialization to or deserialization from QXmlStream.
Definition: Streamer.h:36
QXmlStreamReader * xmlReader()
Returns stream reader or nullptr.
Definition: Streamer.h:48
void assertVersion(unsigned expectedVersion) const
As reader, throws DeserializationException unless the expected version is read. As writer,...
Definition: Streamer.cpp:26
QString const & name(EShape k)
Definition: particles.cpp:20
void rwVector(Streamer &s, const QString &tag, QVector< T > &vec, Args... argsForConstructor)
Serializes a list of items of known and fixed type. Passes optional arguments to the constructor.
Definition: Serialize.h:93