BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
RealSpaceBuilder.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilder.cpp
6 //! @brief Implements class RealSpaceBuilder
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/Const/Units.h"
38 #include <QDebug>
39 
40 namespace {
41 std::unique_ptr<IInterferenceFunction> GetInterferenceFunction(const SessionItem& layoutItem);
42 }
43 
44 RealSpaceBuilder::RealSpaceBuilder(QWidget* parent) : QWidget(parent) {}
45 
47 
49  const SceneGeometry& sceneGeometry,
50  const RealSpace::Camera::Position& cameraPosition)
51 {
52  // default value of cameraPosition is in RealSpaceBuilder.h
53 
54  model->defCamPos = cameraPosition;
55 
56  if (item.modelType() == "MultiLayer")
57  populateMultiLayer(model, item, sceneGeometry);
58 
59  else if (item.modelType() == "Layer")
60  populateLayer(model, item, sceneGeometry);
61 
62  else if (item.modelType() == "ParticleLayout")
63  populateLayout(model, item, sceneGeometry);
64 
65  else if (item.modelType() == "Particle")
67 
68  else if (item.modelType() == "ParticleComposition")
70 
71  else if (item.modelType() == "ParticleCoreShell")
73 
74  else if (item.modelType() == "ParticleDistribution")
76 
77  else if (item.modelType() == "MesoCrystal")
79 }
80 
82  const SceneGeometry& sceneGeometry, const QVector3D&)
83 {
84  double total_height(0.0);
85  int index(0);
86  for (auto layer : item.getItems(MultiLayerItem::T_LAYERS)) {
87 
88  bool isTopLayer = index == 0;
89  populateLayer(model, *layer, sceneGeometry,
90  QVector3D(0, 0, static_cast<float>(-total_height)), isTopLayer);
91 
92  if (index != 0)
93  total_height += TransformTo3D::visualLayerThickness(*layer, sceneGeometry);
94 
95  ++index;
96  }
97 }
98 
100  const SceneGeometry& sceneGeometry, const QVector3D& origin,
101  const bool isTopLayer)
102 {
103  auto layer = TransformTo3D::createLayer(layerItem, sceneGeometry, origin);
104  if (layer && !isTopLayer)
105  model->addBlend(layer.release());
106 
107  for (auto layout : layerItem.getItems(LayerItem::T_LAYOUTS))
108  populateLayout(model, *layout, sceneGeometry, origin);
109 }
110 
112  const SceneGeometry& sceneGeometry, const QVector3D& origin)
113 {
114  ASSERT(layoutItem.modelType() == "ParticleLayout");
115 
116  // If there is no particle to populate
117  if (!layoutItem.getItem(ParticleLayoutItem::T_PARTICLES))
118  return;
119 
120  double layer_size = sceneGeometry.layer_size();
121  double total_density = layoutItem.getItemValue(ParticleLayoutItem::P_TOTAL_DENSITY).toDouble();
122 
123  auto particle3DContainer_vector =
125 
126  auto interference = GetInterferenceFunction(layoutItem);
127 
128  RealSpacePositionBuilder pos_builder;
129  interference->accept(&pos_builder);
130  std::vector<std::vector<double>> lattice_positions =
131  pos_builder.generatePositions(layer_size, total_density);
133  lattice_positions, particle3DContainer_vector, model, sceneGeometry, this);
134 }
135 
137  const SessionItem& particleItem) const
138 {
139  Particle3DContainer particle3DContainer;
140  if (particleItem.modelType() == "Particle") {
141  auto pItem = dynamic_cast<const ParticleItem*>(&particleItem);
142  auto particle = pItem->createParticle();
143  particle3DContainer = RealSpaceBuilderUtils::singleParticle3DContainer(*particle);
144  } else if (particleItem.modelType() == "ParticleCoreShell") {
145  auto particleCoreShellItem = dynamic_cast<const ParticleCoreShellItem*>(&particleItem);
146  // If there is no CORE or SHELL to populate inside ParticleCoreShellItem
147  if (!particleCoreShellItem->getItem(ParticleCoreShellItem::T_CORE)
148  || !particleCoreShellItem->getItem(ParticleCoreShellItem::T_SHELL))
149  return;
150  auto particleCoreShell = particleCoreShellItem->createParticleCoreShell();
151  particle3DContainer =
153  } else if (particleItem.modelType() == "ParticleComposition") {
154  auto particleCompositionItem = dynamic_cast<const ParticleCompositionItem*>(&particleItem);
155  // If there is no particle to populate inside ParticleCompositionItem
156  if (!particleCompositionItem->getItem(ParticleCompositionItem::T_PARTICLES))
157  return;
158  auto particleComposition = particleCompositionItem->createParticleComposition();
159  particle3DContainer =
161  } else if (particleItem.modelType() == "ParticleDistribution") {
162  auto particleDistributionItem =
163  dynamic_cast<const ParticleDistributionItem*>(&particleItem);
164  // If there is no particle to populate inside ParticleDistributionItem
165  if (!particleDistributionItem->getItem(ParticleDistributionItem::T_PARTICLES))
166  return;
167  // show nothing when ParticleDistributionItem is selected
168  } else if (particleItem.modelType() == "MesoCrystal") {
169  auto mesoCrystalItem = dynamic_cast<const MesoCrystalItem*>(&particleItem);
170  // If there is no particle to populate inside MesoCrystalItem
171  if (!mesoCrystalItem->getItem(MesoCrystalItem::T_BASIS_PARTICLE))
172  return;
173  particle3DContainer = RealSpaceBuilderUtils::mesoCrystal3DContainer(*mesoCrystalItem);
174  }
175 
176  populateParticleFromParticle3DContainer(model, particle3DContainer);
177 }
178 
180  RealSpaceModel* model, const Particle3DContainer& particle3DContainer,
181  const QVector3D& lattice_position) const
182 {
183  if (particle3DContainer.containerSize()) {
184  for (size_t i = 0; i < particle3DContainer.containerSize(); ++i) {
185  auto particle3D = particle3DContainer.createParticle(i);
186  particle3D->addTranslation(lattice_position);
187  if (particle3D) {
188  if (!particle3DContainer.particle3DBlend(i))
189  model->add(particle3D.release());
190  else
191  model->addBlend(particle3D.release()); // use addBlend() for transparent object
192  }
193  }
194  }
195 }
196 
197 namespace {
198 std::unique_ptr<IInterferenceFunction> GetInterferenceFunction(const SessionItem& layoutItem)
199 {
200  auto interferenceLattice = layoutItem.getItem(ParticleLayoutItem::T_INTERFERENCE);
201  if (interferenceLattice) {
202  auto interferenceItem = static_cast<const InterferenceFunctionItem*>(interferenceLattice);
203  auto P_interference = interferenceItem->createInterferenceFunction();
204  if (P_interference)
205  return std::unique_ptr<IInterferenceFunction>(P_interference.release());
206  }
207  return std::make_unique<InterferenceFunctionNone>();
208 }
209 } // namespace
#define ASSERT(condition)
Definition: Assert.h:31
Defines class ExternalProperty.
Defines InterferenceFunctionItems's classes.
Includes all interference function definitions.
Defines classes Lattice2DItems.
Defines class LayerItem.
Defines class MesoCrystalItem.
Defines class MultiLayerItem.
Implements namespace TransformTo3D.
Defines class ParticleCompositionItem.
Defines class ParticleCoreShellItem.
Defines ParticleCoreShell.
Defines class ParticleDistributionItem.
Defines class ParticleItem.
Defines class ParticleLayoutItem.
Defines class Particle.
Defines RealSpaceBuilderUtils namespace.
Defines class RealSpaceBuilder.
Defines class RealSpaceCanvas.
Defines RealSpaceModel namespace.
Defines class RealSpacePositionBuilder.
Defines namespace TransformTo3D.
Defines some unit conversion factors and other constants in namespace Units.
Defines class VectorItem.
virtual std::unique_ptr< IInterferenceFunction > createInterferenceFunction() const =0
static const QString T_LAYOUTS
Definition: LayerItem.h:26
static const QString T_BASIS_PARTICLE
static const QString T_LAYERS
std::unique_ptr< RealSpace::Particles::Particle > createParticle(const size_t &index) const
size_t containerSize() const
bool particle3DBlend(const size_t &index) const
static const QString T_PARTICLES
std::unique_ptr< ParticleComposition > createParticleComposition() const
static const QString T_CORE
static const QString T_SHELL
std::unique_ptr< ParticleCoreShell > createParticleCoreShell() const
static const QString T_PARTICLES
std::unique_ptr< Particle > createParticle() const
static const QString T_PARTICLES
static const QString T_INTERFERENCE
static const QString P_TOTAL_DENSITY
void populateParticleFromParticleItem(RealSpaceModel *model, const SessionItem &particleItem) const
void populate(RealSpaceModel *model, const SessionItem &item, const SceneGeometry &sceneGeometry, const RealSpace::Camera::Position &cameraPosition=RealSpace::Camera::Position(RealSpace::Vector3D(0, -200, 120), RealSpace::Vector3D(0, 0, 0), RealSpace::Vector3D::_z))
RealSpaceBuilder(QWidget *parent=nullptr)
void populateLayer(RealSpaceModel *model, const SessionItem &layerItem, const SceneGeometry &sceneGeometry, const QVector3D &origin={}, const bool isTopLayer=false)
void populateLayout(RealSpaceModel *model, const SessionItem &layoutItem, const SceneGeometry &sceneGeometry, const QVector3D &origin={})
void populateMultiLayer(RealSpaceModel *model, const SessionItem &item, const SceneGeometry &sceneGeometry, const QVector3D &origin={})
void populateParticleFromParticle3DContainer(RealSpaceModel *model, const Particle3DContainer &particle3DContainer, const QVector3D &lattice_position={}) const
std::vector< std::vector< double > > generatePositions(double layer_size, double density=0.0) const
Camera::Position defCamPos
Definition: model.h:53
void add(Object *)
Definition: model.cpp:119
void addBlend(Object *)
Definition: model.cpp:127
double layer_size() const
QVector< SessionItem * > getItems(const QString &tag="") const
Returns vector of all items of given tag.
QVariant getItemValue(const QString &tag) const
Directly access value of item under given tag.
QString modelType() const
Get model type.
SessionItem * getItem(const QString &tag="", int row=0) const
Returns item in given row of given tag.
Particle3DContainer particleCoreShell3DContainer(const ParticleCoreShell &particleCoreShell, double total_abundance=1.0, const QVector3D &origin={})
Particle3DContainer particleComposition3DContainer(const ParticleComposition &particleComposition3DContainer, double total_abundance=1.0, const QVector3D &origin={})
void populateParticlesAtLatticePositions(const std::vector< std::vector< double >> &lattice_positions, const std::vector< Particle3DContainer > &particle3DContainer_vector, RealSpaceModel *model, const SceneGeometry &sceneGeometry, const RealSpaceBuilder *builder3D)
std::vector< Particle3DContainer > particle3DContainerVector(const SessionItem &layoutItem, const QVector3D &origin={})
Particle3DContainer mesoCrystal3DContainer(const MesoCrystalItem &mesoCrystalItem, double total_abundance=1.0, const QVector3D &origin={})
Particle3DContainer singleParticle3DContainer(const Particle &particle, double total_abundance=1.0, const QVector3D &origin={})
std::unique_ptr< RealSpace::Layer > createLayer(const SessionItem &layerItem, const SceneGeometry &sceneGeometry, const QVector3D &origin={})
double visualLayerThickness(const SessionItem &layerItem, const SceneGeometry &sceneGeometry)