Skip to content
Snippets Groups Projects
MaterialItem.h 3.63 KiB
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/Model/Material/MaterialItem.h
//! @brief     Defines class MaterialItem
//!
//! @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_MATERIAL_MATERIALITEM_H
#define BORNAGAIN_GUI_MODEL_MATERIAL_MATERIALITEM_H

#include <QColor>
#include <QObject>
#include <heinz/Complex.h>
#include <heinz/Vectors3D.h>
#include <memory>
#include <variant>

class Material;
class DoubleDescriptor;
class VectorDescriptor;
class QXmlStreamReader;
class QXmlStreamWriter;

class MaterialItem : public QObject {
    Q_OBJECT

public:
    MaterialItem();

    //! Creates a complete copy, also the identifier is the same.
    //!
    //! Note that the base QObject is freshly initialized, not copied from \a other. Therefore
    //! object hierarchy, connections, properties, object name or similar things are not copied.
    //! This is of no harm since this class is only derived from QObject to provide data change
    //! signaling.
    MaterialItem(const MaterialItem& other);

    //! Turns material into refractive index material.
    //!
    //! Set refractive index as in 1 - delta + i * beta
    void setRefractiveIndex(double delta, double beta);

    //! Turns material into SLD based material.
    void setScatteringLengthDensity(complex_t sld);

    DoubleDescriptor delta();
    DoubleDescriptor beta();
    DoubleDescriptor sldRe();
    DoubleDescriptor sldIm();
    VectorDescriptor magnetizationVector();

    /// \return true if refractive index was given, otherwise SLD was given
    bool hasRefractiveIndex() const;

    QString materialName() const;
    void setMaterialName(const QString& name);

    QString identifier() const;
    void setIdentifier(const QString& id);
    void createNewIdentifier();

    QColor color() const;
    void setColor(const QColor& color);

    R3 magnetization() const;
    void setMagnetization(const R3& magnetization);

    std::unique_ptr<Material> createMaterial() const;

    //! Compares all contents. The inactive contents (e.g. SLD in case of refractive) are not taken
    //! into account.
    bool operator==(const MaterialItem& other) const;
    bool operator!=(const MaterialItem& other) const;

    void writeContentTo(QXmlStreamWriter* writer) const;
    void readContentFrom(QXmlStreamReader* reader);

    //! Updates content from the other material.
    //!
    //! Does NOT change the identifier.
    //! emits dataChanged, if differences exist.
    void updateFrom(const MaterialItem& other);

private:
    //! Returns a unique identifier for descriptors.
    //!
    //! lastPart will be attached to identify the relevant descriptor.
    QString uidForDescriptor(const QString& lastPart) const;

signals:
    void dataChanged() const;

private:
    QString m_name;
    QString m_id;
    QColor m_color;

    struct Refractive {
        Refractive(double d, double b) : delta(d), beta(b) {}
        double delta = 0.0;
        double beta = 0.0;
        bool operator==(const Refractive& o) const { return delta == o.delta && beta == o.beta; }
        bool operator!=(const Refractive& o) const { return !operator==(o); }
    };

    std::variant<Refractive, complex_t> m_data;
    R3 m_magnetization;
};

#endif // BORNAGAIN_GUI_MODEL_MATERIAL_MATERIALITEM_H