1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
// ************************************************************************** //
//
// BornAgain: simulate and fit scattering at grazing incidence
//
//! @file GUI/ba3d/model/geometry.h
//! @brief Defines Geometry class
//!
//! @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_BA3D_MODEL_GEOMETRY_H
#define BORNAGAIN_GUI_BA3D_MODEL_GEOMETRY_H
#include "GUI/ba3d/model/geometry_inc.h"
#include <QObject>
#include <QVector>
#include <unordered_map>
#include <vector>
namespace RealSpace
{
class Buffer;
class GeometryStore;
class Geometry
{
friend class Buffer;
friend class GeometryStore;
public:
// vertex + normal pair
struct Vert_Normal {
Vector3D v, n;
Vert_Normal() = default;
Vert_Normal(const Vector3D& v, const Vector3D& n);
};
// vertex indices (for GL)
using Indices = std::vector<unsigned>;
// vertices (for GL)
struct Vertices : private QVector<Vector3D> {
using QVector::append;
using QVector::QVector;
using QVector::reserve;
using QVector::resize;
using QVector::operator[];
using QVector::at;
using QVector::begin;
using QVector::count;
using QVector::end;
void addVertex(const Vector3D&, int n = 1); // add a vertex, possibly multiple copies
void addTriangle(const Vector3D&, const Vector3D&, const Vector3D&); // triangle
void addQuad(const Vector3D&, const Vector3D&, const Vector3D&,
const Vector3D&); // quad as 2 triangles
void addQuad(const Vertices&, unsigned, unsigned, unsigned, unsigned); // quad by indices
void addStrip(const Vertices&, const Indices&); // triangle strip
void addFan(const Vertices&, const Indices&); // triangle fan
};
// vertex/normal mesh
using Mesh = QVector<Vert_Normal>;
Geometry(GeometricID::Key);
virtual ~Geometry();
private:
GeometricID::Key m_key;
Mesh m_mesh;
// make a mesh from vectors of vertices and (optionally) normals
static Mesh makeMesh(const Vertices& vs, Vertices const* ns = nullptr);
static Mesh makeMesh(const Vertices& vs, const Vertices& ns);
static Mesh meshPlane();
static Mesh meshBox();
static Mesh meshSphere(float cut, float baseShift = 0.0f, float removedTop = 0.0f);
static Mesh meshColumn(float ratio_Rt_Rb, float numSides);
static Mesh meshIcosahedron();
static Mesh meshDodecahedron();
static Mesh meshTruncBox(float tD);
static Mesh meshCuboctahedron(float rH, float alpha, float H);
static Mesh meshRipple(float numSides, float ratio_asymmetry_W);
// mesh params for round shapes
static int const RINGS = 12, SLICES = 24;
};
// a single store keeps existing geometries for sharing
class GeometryStore : public QObject
{
Q_OBJECT
friend class Geometry;
public:
GeometryHandle getGeometry(GeometricID::Key);
signals:
void deletingGeometry(Geometry const*); // signal to canvases
private:
std::unordered_map<GeometricID::Key, GeometryRef, GeometricID::KeyHash> m_geometries;
void geometryDeleted(Geometry const&); // ~Geometry() calls this
};
GeometryStore& geometryStore(); // simpleton
} // namespace RealSpace
#endif // BORNAGAIN_GUI_BA3D_MODEL_GEOMETRY_H
|