BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
TransformTo3D.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/TransformTo3D.cpp
6 //! @brief Implements namespace TransformTo3D
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"
27 
28 namespace {
29 bool isTopLayer(const SessionItem& layerItem)
30 {
31  auto layers = layerItem.parent()->getItems(MultiLayerItem::T_LAYERS);
32  return layers.indexOf(const_cast<SessionItem*>(&layerItem)) == 0;
33 }
34 bool isBottomLayer(const SessionItem& layerItem)
35 {
36  auto layers = layerItem.parent()->getItems(MultiLayerItem::T_LAYERS);
37  return layers.indexOf(const_cast<SessionItem*>(&layerItem)) == layers.size() - 1;
38 }
39 } // namespace
40 
42  const SceneGeometry& sceneGeometry)
43 {
44  ASSERT(layerItem.modelType() == "Layer");
45 
46  double thickness(0.0);
47  if (isTopLayer(layerItem))
48  thickness = sceneGeometry.layer_top_thickness();
49  else if (isBottomLayer(layerItem))
50  thickness = sceneGeometry.layer_bottom_thickness();
51  else
52  thickness = layerItem.getItemValue(LayerItem::P_THICKNESS).toDouble();
53 
54  return thickness == 0.0 ? sceneGeometry.layer_min_thickness() : thickness;
55 }
56 
57 std::unique_ptr<RealSpace::Layer> TransformTo3D::createLayer(const SessionItem& layerItem,
58  const SceneGeometry& sceneGeometry,
59  const QVector3D& origin)
60 {
61  ASSERT(layerItem.modelType() == "Layer");
62 
63  double thickness = TransformTo3D::visualLayerThickness(layerItem, sceneGeometry);
64 
65  double s2 = sceneGeometry.layer_size();
66  double ztop = static_cast<double>(origin.z());
67  double zbottom = static_cast<double>(origin.z()) - thickness;
68 
69  std::unique_ptr<RealSpace::Layer> result =
70  std::make_unique<RealSpace::Layer>(RealSpace::VectorRange(
71  RealSpace::Range(static_cast<float>(-s2), static_cast<float>(+s2)),
72  RealSpace::Range(static_cast<float>(-s2), static_cast<float>(+s2)),
73  RealSpace::Range(static_cast<float>(ztop), static_cast<float>(zbottom))));
74 
75  QColor color = layerItem.getItemValue(LayerItem::P_MATERIAL).value<ExternalProperty>().color();
76  color.setAlphaF(.3);
77 
78  result->color = color;
79 
80  return result;
81 }
82 
83 std::unique_ptr<RealSpace::Particles::Particle>
85 {
86  ASSERT(particleItem.modelType() == "Particle");
87 
88  std::unique_ptr<RealSpace::Particles::Particle> result;
89 
90  auto ffItem =
91  static_cast<FormFactorItem*>(particleItem.getGroupItem(ParticleItem::P_FORM_FACTOR));
92 
93  auto unique_ff = ffItem->createFormFactor();
94 
95  result = createParticlefromIFormFactor(unique_ff.get());
96 
97  return result;
98 }
99 
100 std::unique_ptr<RealSpace::Particles::Particle>
102 {
103  std::unique_ptr<RealSpace::Particles::Particle> result;
104 
105  if (auto ff_AnisoPyramid = dynamic_cast<const FormFactorAnisoPyramid*>(ff)) {
106  double length = ff_AnisoPyramid->getLength();
107  double width = ff_AnisoPyramid->getWidth();
108  double height = ff_AnisoPyramid->getHeight();
109  double alpha = ff_AnisoPyramid->getAlpha();
110  result = std::make_unique<RealSpace::Particles::AnisoPyramid>(length, width, height, alpha);
111  } else if (auto ff_BarGauss = dynamic_cast<const FormFactorBarGauss*>(ff)) {
112  double length = ff_BarGauss->getLength();
113  double width = ff_BarGauss->getWidth();
114  double height = ff_BarGauss->getHeight();
115  result = std::make_unique<RealSpace::Particles::BarGauss>(length, width, height);
116  } else if (auto ff_BarLorentz = dynamic_cast<const FormFactorBarLorentz*>(ff)) {
117  double length = ff_BarLorentz->getLength();
118  double width = ff_BarLorentz->getWidth();
119  double height = ff_BarLorentz->getHeight();
120  result = std::make_unique<RealSpace::Particles::BarLorentz>(length, width, height);
121  } else if (auto ff_Box = dynamic_cast<const FormFactorBox*>(ff)) {
122  double length = ff_Box->getLength();
123  double width = ff_Box->getWidth();
124  double height = ff_Box->getHeight();
125  result = std::make_unique<RealSpace::Particles::Box>(length, width, height);
126  } else if (auto ff_Cone = dynamic_cast<const FormFactorCone*>(ff)) {
127  double radius = ff_Cone->getRadius();
128  double height = ff_Cone->getHeight();
129  double alpha = ff_Cone->getAlpha();
130  result = std::make_unique<RealSpace::Particles::Cone>(radius, height, alpha);
131  } else if (auto ff_Cone6 = dynamic_cast<const FormFactorCone6*>(ff)) {
132  double baseedge = ff_Cone6->getBaseEdge();
133  double height = ff_Cone6->getHeight();
134  double alpha = ff_Cone6->getAlpha();
135  result = std::make_unique<RealSpace::Particles::Cone6>(baseedge, height, alpha);
136  } else if (auto ff_Cuboctahedron = dynamic_cast<const FormFactorCuboctahedron*>(ff)) {
137  double length = ff_Cuboctahedron->getLength();
138  double height = ff_Cuboctahedron->getHeight();
139  double height_ratio = ff_Cuboctahedron->getHeightRatio();
140  double alpha = ff_Cuboctahedron->getAlpha();
141  result = std::make_unique<RealSpace::Particles::Cuboctahedron>(length, height, height_ratio,
142  alpha);
143  } else if (auto ff_Cylinder = dynamic_cast<const FormFactorCylinder*>(ff)) {
144  double radius = ff_Cylinder->getRadius();
145  double height = ff_Cylinder->getHeight();
146  result = std::make_unique<RealSpace::Particles::Cylinder>(radius, height);
147  } else if (auto ff_Dodecahedron = dynamic_cast<const FormFactorDodecahedron*>(ff)) {
148  double edge = ff_Dodecahedron->getEdge();
149  result = std::make_unique<RealSpace::Particles::Dodecahedron>(edge);
150  } else if (auto ff_Dot = dynamic_cast<const FormFactorDot*>(ff)) {
151  Q_UNUSED(ff_Dot);
152  result = std::make_unique<RealSpace::Particles::Dot>();
153  } else if (auto ff_EllipsoidalCylinder =
154  dynamic_cast<const FormFactorEllipsoidalCylinder*>(ff)) {
155  double radius_x = ff_EllipsoidalCylinder->getRadiusX();
156  double radius_y = ff_EllipsoidalCylinder->getRadiusY();
157  double height = ff_EllipsoidalCylinder->getHeight();
158  result =
159  std::make_unique<RealSpace::Particles::EllipsoidalCylinder>(radius_x, radius_y, height);
160  } else if (auto ff_FullSphere = dynamic_cast<const FormFactorFullSphere*>(ff)) {
161  double radius = ff_FullSphere->getRadius();
162  result = std::make_unique<RealSpace::Particles::FullSphere>(radius);
163  } else if (auto ff_FullSpheroid = dynamic_cast<const FormFactorFullSpheroid*>(ff)) {
164  double radius = ff_FullSpheroid->getRadius();
165  double height = ff_FullSpheroid->getHeight();
166  result = std::make_unique<RealSpace::Particles::FullSpheroid>(radius, height);
167  } else if (auto ff_HemiEllipsoid = dynamic_cast<const FormFactorHemiEllipsoid*>(ff)) {
168  double radius_x = ff_HemiEllipsoid->getRadiusX();
169  double radius_y = ff_HemiEllipsoid->getRadiusY();
170  double height = ff_HemiEllipsoid->getHeight();
171  result = std::make_unique<RealSpace::Particles::HemiEllipsoid>(radius_x, radius_y, height);
172  } else if (auto ff_Icosahedron = dynamic_cast<const FormFactorIcosahedron*>(ff)) {
173  double edge = ff_Icosahedron->getEdge();
174  result = std::make_unique<RealSpace::Particles::Icosahedron>(edge);
175  } else if (auto ff_Prism3 = dynamic_cast<const FormFactorPrism3*>(ff)) {
176  double baseedge = ff_Prism3->getBaseEdge();
177  double height = ff_Prism3->getHeight();
178  result = std::make_unique<RealSpace::Particles::Prism3>(baseedge, height);
179  } else if (auto ff_Prism6 = dynamic_cast<const FormFactorPrism6*>(ff)) {
180  double baseedge = ff_Prism6->getBaseEdge();
181  double height = ff_Prism6->getHeight();
182  result = std::make_unique<RealSpace::Particles::Prism6>(baseedge, height);
183  } else if (auto ff_Pyramid = dynamic_cast<const FormFactorPyramid*>(ff)) {
184  double baseedge = ff_Pyramid->getBaseEdge();
185  double height = ff_Pyramid->getHeight();
186  double alpha = ff_Pyramid->getAlpha();
187  result = std::make_unique<RealSpace::Particles::Pyramid>(baseedge, height, alpha);
188  } else if (auto ff_CosineRippleBox = dynamic_cast<const FormFactorCosineRippleBox*>(ff)) {
189  double length = ff_CosineRippleBox->getLength();
190  double width = ff_CosineRippleBox->getWidth();
191  double height = ff_CosineRippleBox->getHeight();
192  result = std::make_unique<RealSpace::Particles::CosineRippleBox>(length, width, height);
193  } else if (auto ff_CosineRippleGauss = dynamic_cast<const FormFactorCosineRippleGauss*>(ff)) {
194  double length = ff_CosineRippleGauss->getLength();
195  double width = ff_CosineRippleGauss->getWidth();
196  double height = ff_CosineRippleGauss->getHeight();
197  result = std::make_unique<RealSpace::Particles::CosineRippleGauss>(length, width, height);
198  } else if (auto ff_CosineRippleLorentz =
199  dynamic_cast<const FormFactorCosineRippleLorentz*>(ff)) {
200  double length = ff_CosineRippleLorentz->getLength();
201  double width = ff_CosineRippleLorentz->getWidth();
202  double height = ff_CosineRippleLorentz->getHeight();
203  result = std::make_unique<RealSpace::Particles::CosineRippleLorentz>(length, width, height);
204  } else if (auto ff_SawtoothRippleBox = dynamic_cast<const FormFactorSawtoothRippleBox*>(ff)) {
205  double length = ff_SawtoothRippleBox->getLength();
206  double width = ff_SawtoothRippleBox->getWidth();
207  double height = ff_SawtoothRippleBox->getHeight();
208  result = std::make_unique<RealSpace::Particles::SawtoothRippleBox>(length, width, height);
209  } else if (auto ff_SawtoothRippleGauss =
210  dynamic_cast<const FormFactorSawtoothRippleGauss*>(ff)) {
211  double length = ff_SawtoothRippleGauss->getLength();
212  double width = ff_SawtoothRippleGauss->getWidth();
213  double height = ff_SawtoothRippleGauss->getHeight();
214  result = std::make_unique<RealSpace::Particles::SawtoothRippleGauss>(length, width, height);
215  } else if (auto ff_SawtoothRippleLorentz =
216  dynamic_cast<const FormFactorSawtoothRippleLorentz*>(ff)) {
217  double length = ff_SawtoothRippleLorentz->getLength();
218  double width = ff_SawtoothRippleLorentz->getWidth();
219  double height = ff_SawtoothRippleLorentz->getHeight();
220  result =
221  std::make_unique<RealSpace::Particles::SawtoothRippleLorentz>(length, width, height);
222  } else if (auto ff_Tetrahedron = dynamic_cast<const FormFactorTetrahedron*>(ff)) {
223  double baseedge = ff_Tetrahedron->getBaseEdge();
224  double height = ff_Tetrahedron->getHeight();
225  double alpha = ff_Tetrahedron->getAlpha();
226  result = std::make_unique<RealSpace::Particles::Tetrahedron>(baseedge, height, alpha);
227  } else if (auto ff_TruncatedCube = dynamic_cast<const FormFactorTruncatedCube*>(ff)) {
228  double length = ff_TruncatedCube->getLength();
229  double removed_length = ff_TruncatedCube->getRemovedLength();
230  result = std::make_unique<RealSpace::Particles::TruncatedCube>(length, removed_length);
231  } else if (auto ff_TruncatedSphere = dynamic_cast<const FormFactorTruncatedSphere*>(ff)) {
232  double radius = ff_TruncatedSphere->getRadius();
233  double height = ff_TruncatedSphere->getHeight();
234  double deltaH = ff_TruncatedSphere->getRemovedTop();
235  result = std::make_unique<RealSpace::Particles::TruncatedSphere>(radius, height, deltaH);
236  } else if (auto ff_TruncatedSpheroid = dynamic_cast<const FormFactorTruncatedSpheroid*>(ff)) {
237  double radius = ff_TruncatedSpheroid->getRadius();
238  double height = ff_TruncatedSpheroid->getHeight();
239  double hfc = ff_TruncatedSpheroid->getHeightFlattening();
240  double deltaH = ff_TruncatedSpheroid->getRemovedTop();
241  result =
242  std::make_unique<RealSpace::Particles::TruncatedSpheroid>(radius, height, hfc, deltaH);
243  }
244 
245  return result;
246 }
#define ASSERT(condition)
Definition: Assert.h:31
Defines class ExternalProperty.
Defines FormFactorItems classes.
Defines class GUIDomainSampleVisitor.
Includes all particle-shape form-factor definitions.
Defines class LayerItem.
Defines class MultiLayerItem.
Defines class ParticleCompositionItem.
Defines class ParticleItem.
Defines class RealSpaceCanvas.
Defines namespace TransformTo3D.
Defines some unit conversion factors and other constants in namespace Units.
Defines class VectorItem.
The ExternalProperty class defines custom QVariant property to carry the text, color and an identifie...
A frustum (truncated pyramid) with rectangular base.
The form factor of an elongated bar, with Gaussian profile in elongation direction.
Definition: FormFactorBar.h:27
The form factor of an elongated, with Lorentz form factor in elongation direction.
Definition: FormFactorBar.h:40
A rectangular prism (parallelepiped).
Definition: FormFactorBox.h:23
A frustum (truncated pyramid) with regular hexagonal base.
A conical frustum (cone truncated parallel to the base) with circular base.
The form factor for a cosine ripple, with box profile in elongation direction.
The form factor for a cosine ripple, with Gaussian profile in elongation direction.
The form factor for a cosine ripple, with Lorentz form factor in elongation direction.
A truncated bifrustum with quadratic base.
A circular cylinder.
A regular dodecahedron.
A dot, with scattering power as a sphere of radius rscat, but with F(q)=const.
Definition: FormFactorDot.h:23
A cylinder with elliptical base.
A full spheroid (an ellipsoid with two equal axes, hence with circular cross section)
An hemi ellipsoid, obtained by truncating a full ellipsoid in the middle plane spanned by two princip...
A regular icosahedron.
virtual std::unique_ptr< IFormFactor > createFormFactor() const =0
A prism based on an equilateral triangle.
A prism based on a regular hexagonal.
A frustum with a quadratic base.
The form factor for a cosine ripple, with box profile in elongation direction.
The form factor for a cosine ripple, with Gaussian profile in elongation direction.
The form factor for a cosine ripple, with Lorentz form factor in elongation direction.
A frustum with equilateral trigonal base.
A cube, with tetrahedral truncation of all corners.
Abstract base class for all form factors.
Definition: IFormFactor.h:36
static const QString P_MATERIAL
Definition: LayerItem.h:24
static const QString P_THICKNESS
Definition: LayerItem.h:22
static const QString T_LAYERS
static const QString P_FORM_FACTOR
Definition: ParticleItem.h:25
double layer_top_thickness() const
double layer_min_thickness() const
double layer_bottom_thickness() const
double layer_size() const
SessionItem * getGroupItem(const QString &groupName) const
Access subitem of group item.
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.
SessionItem * parent() const
Returns parent of this item.
Definition: SessionItem.cpp:73
QString modelType() const
Get model type.
std::unique_ptr< RealSpace::Layer > createLayer(const SessionItem &layerItem, const SceneGeometry &sceneGeometry, const QVector3D &origin={})
std::unique_ptr< RealSpace::Particles::Particle > createParticlefromIFormFactor(const IFormFactor *ff)
double visualLayerThickness(const SessionItem &layerItem, const SceneGeometry &sceneGeometry)
std::unique_ptr< RealSpace::Particles::Particle > createParticle3D(const SessionItem &particleItem)