BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
GUI::RealSpace::Geometry Class Reference

Description

Definition at line 29 of file geometry.h.

Collaboration diagram for GUI::RealSpace::Geometry:
[legend]

Classes

struct  Vert_Normal
 
struct  Vertices
 

Public Types

using Indices = std::vector< unsigned >
 
using Mesh = QVector< Vert_Normal >
 

Public Member Functions

 Geometry (GeometricID::Key)
 
virtual ~Geometry ()
 

Static Private Member Functions

static Mesh makeMesh (const Vertices &vs, const Vertices &ns)
 
static Mesh makeMesh (const Vertices &vs, Vertices const *ns=nullptr)
 
static Mesh meshBipyramid4 (float rH, float alpha, float H)
 
static Mesh meshBox ()
 
static Mesh meshColumn (float ratio_Rt_Rb, float numSides)
 
static Mesh meshDodecahedron ()
 
static Mesh meshIcosahedron ()
 
static Mesh meshPlane ()
 
static Mesh meshRipple (float numSides, float ratio_asymmetry_W)
 
static Mesh meshSphere (float cut, float baseShift=0.0f, float removedTop=0.0f)
 
static Mesh meshTruncBox (float tD)
 

Private Attributes

GeometricID::Key m_key
 
Mesh m_mesh
 

Static Private Attributes

static int const RINGS = 12
 
static int const SLICES = 24
 

Friends

class Buffer
 
class GeometryStore
 

Member Typedef Documentation

◆ Indices

using GUI::RealSpace::Geometry::Indices = std::vector<unsigned>

Definition at line 42 of file geometry.h.

◆ Mesh

Definition at line 66 of file geometry.h.

Constructor & Destructor Documentation

◆ Geometry()

GUI::RealSpace::Geometry::Geometry ( GeometricID::Key  key_)

Definition at line 75 of file geometry.cpp.

76  : m_key(key_)
77 {
78  using namespace GeometricID;
79 
80  switch (m_key.id) {
81  case BaseShape::Plane:
82  m_mesh = meshPlane();
83  break;
84  case BaseShape::Box:
85  m_mesh = meshBox();
86  break;
87  case BaseShape::Sphere:
89  break;
90  case BaseShape::Column:
92  break;
93  case BaseShape::Icosahedron:
95  break;
96  case BaseShape::Dodecahedron:
98  break;
99  case BaseShape::TruncatedBox:
101  break;
102  case BaseShape::Bipyramid4:
104  break;
105  case BaseShape::Ripple:
107  break;
108  }
109 }
static Mesh meshPlane()
Definition: plane.cpp:20
static Mesh meshBox()
Definition: box.cpp:20
GeometricID::Key m_key
Definition: geometry.h:72
static Mesh meshColumn(float ratio_Rt_Rb, float numSides)
Definition: column.cpp:22
static Mesh meshBipyramid4(float rH, float alpha, float H)
static Mesh meshTruncBox(float tD)
Definition: truncbox.cpp:20
static Mesh meshDodecahedron()
static Mesh meshIcosahedron()
Definition: icosahedron.cpp:22
static Mesh meshSphere(float cut, float baseShift=0.0f, float removedTop=0.0f)
Definition: sphere.cpp:24
static Mesh meshRipple(float numSides, float ratio_asymmetry_W)
Definition: ripple.cpp:21

References GUI::RealSpace::GeometricID::Key::id, m_key, m_mesh, meshBipyramid4(), meshBox(), meshColumn(), meshDodecahedron(), meshIcosahedron(), meshPlane(), meshRipple(), meshSphere(), meshTruncBox(), GUI::RealSpace::GeometricID::Key::p1, GUI::RealSpace::GeometricID::Key::p2, and GUI::RealSpace::GeometricID::Key::p3.

Referenced by GUI::RealSpace::GeometryStore::getGeometry().

Here is the call graph for this function:

◆ ~Geometry()

GUI::RealSpace::Geometry::~Geometry ( )
virtual

Definition at line 111 of file geometry.cpp.

112 {
113  // remove self from the store
115 }
void geometryDeleted(Geometry const &)
Definition: geometry.cpp:170
GeometryStore & geometryStore()
Definition: geometry.cpp:176

References GUI::RealSpace::GeometryStore::geometryDeleted(), and GUI::RealSpace::geometryStore().

Here is the call graph for this function:

Member Function Documentation

◆ makeMesh() [1/2]

Geometry::Mesh GUI::RealSpace::Geometry::makeMesh ( const Vertices vs,
const Vertices ns 
)
staticprivate

Definition at line 151 of file geometry.cpp.

152 {
153  return makeMesh(vs, &ns);
154 }
static Mesh makeMesh(const Vertices &vs, Vertices const *ns=nullptr)
Definition: geometry.cpp:117

References makeMesh().

Here is the call graph for this function:

◆ makeMesh() [2/2]

Geometry::Mesh GUI::RealSpace::Geometry::makeMesh ( const Vertices vs,
Vertices const *  ns = nullptr 
)
staticprivate

Definition at line 117 of file geometry.cpp.

118 {
119  int nv = vs.count();
120  ASSERT(0 == nv % 3);
121  ASSERT(!ns || nv == ns->count()); // if normals not given, will be computed
122 
123  Mesh mesh(nv);
124 
125  for (int i = 0; i < nv; i += 3) {
126  const Vector3D& v0 = vs.at(0 + i);
127  const Vector3D& v1 = vs.at(1 + i);
128  const Vector3D& v2 = vs.at(2 + i);
129  const Vector3D* n0;
130  const Vector3D* n1;
131  const Vector3D* n2;
132  Vector3D nm;
133 
134  if (ns) {
135  n0 = &ns->at(0 + i);
136  n1 = &ns->at(1 + i);
137  n2 = &ns->at(2 + i);
138  } else {
139  nm = cross((v1 - v0), (v2 - v0));
140  n0 = n1 = n2 = &nm;
141  }
142 
143  mesh.append(Vert_Normal(v0, *n0));
144  mesh.append(Vert_Normal(v1, *n1));
145  mesh.append(Vert_Normal(v2, *n2));
146  }
147 
148  return mesh;
149 }
QVector< Vert_Normal > Mesh
Definition: geometry.h:66
Vector3D cross(const Vector3D &v1, const Vector3D &v2)
Definition: def.cpp:67

References GUI::RealSpace::cross().

Referenced by makeMesh(), meshBipyramid4(), meshBox(), meshColumn(), meshDodecahedron(), meshIcosahedron(), meshPlane(), meshRipple(), meshSphere(), and meshTruncBox().

Here is the call graph for this function:

◆ meshBipyramid4()

Geometry::Mesh GUI::RealSpace::Geometry::meshBipyramid4 ( float  rH,
float  alpha,
float  H 
)
staticprivate

Definition at line 21 of file cuboctahedron.cpp.

22 { // t/D
23 
24  // alpha is the angle between the common square interface and one of the side faces (alpha for
25  // both the two truncated pyramids is the same)
26 
27  // H here is the normalized height of the cuboctahedron i.e. H/L (see particles.cpp)
28 
29  ASSERT(alpha <= float(M_PI_2));
30  ASSERT(rH >= 0);
31 
32  float const D = .5f, t = tanf(float(M_PI_2) - alpha);
33  float const Db = D - t * H, Dt = D - t * rH * H;
34 
35  Vertices vs_;
36  vs_.reserve(12);
37  float z[] = {0, H, H * (rH + 1)},
38  d[] = {Db, D, Dt}; // keep bottom of the cuboctahedron in z=0 plane
39  for (int i = 0; i < 3; ++i)
40  for (int x : {-1, +1})
41  for (int y : {-1, +1}) {
42  float di = d[i];
43  vs_.append(Vector3D(x * di, y * di, z[i]));
44  }
45 
46  ASSERT(12 == vs_.count());
47 
48  Vertices vs;
49  vs.reserve(60);
50 
51  vs.addQuad(vs_, 0, 1, 3, 2);
52  vs.addQuad(vs_, 8, 10, 11, 9);
53  vs.addQuad(vs_, 0, 4, 5, 1);
54  vs.addQuad(vs_, 1, 5, 7, 3);
55  vs.addQuad(vs_, 3, 7, 6, 2);
56  vs.addQuad(vs_, 2, 6, 4, 0);
57  vs.addQuad(vs_, 4, 8, 9, 5);
58  vs.addQuad(vs_, 5, 9, 11, 7);
59  vs.addQuad(vs_, 7, 11, 10, 6);
60  vs.addQuad(vs_, 6, 10, 8, 4);
61 
62  ASSERT(60 == vs.count());
63 
64  return makeMesh(vs);
65 }

References GUI::RealSpace::Geometry::Vertices::addQuad(), and makeMesh().

Referenced by Geometry().

Here is the call graph for this function:

◆ meshBox()

Geometry::Mesh GUI::RealSpace::Geometry::meshBox ( )
staticprivate

Definition at line 20 of file box.cpp.

21 {
22  float const D = .5f;
23 
24  Vertices vs_;
25  vs_.reserve(8);
26  for (float x : {-D, +D})
27  for (float y : {-D, +D})
28  for (float z : {-D, +D})
29  vs_.append(Vector3D(x, y, z));
30 
31  ASSERT(8 == vs_.count());
32 
33  Vertices vs;
34  vs.reserve(36);
35 
36  vs.addQuad(vs_, 0, 2, 6, 4);
37  vs.addQuad(vs_, 1, 5, 7, 3);
38  vs.addQuad(vs_, 0, 1, 3, 2);
39  vs.addQuad(vs_, 4, 6, 7, 5);
40  vs.addQuad(vs_, 0, 4, 5, 1);
41  vs.addQuad(vs_, 2, 3, 7, 6);
42 
43  ASSERT(36 == vs.count());
44 
45  return makeMesh(vs);
46 }

References GUI::RealSpace::Geometry::Vertices::addQuad(), and makeMesh().

Referenced by Geometry(), and meshTruncBox().

Here is the call graph for this function:

◆ meshColumn()

Geometry::Mesh GUI::RealSpace::Geometry::meshColumn ( float  ratio_Rt_Rb,
float  numSides 
)
staticprivate

Definition at line 22 of file column.cpp.

23 {
24  int const sides = qRound(numSides);
25  bool const smooth = (0 == sides); // sides = 0 implies smooth -> e.g. cylinder
26  int const slices = smooth ? SLICES : sides;
27 
28  // Rt is the top radius, Rb is the bottom radius, H is the height
29  // Values are chosen such that diameter and height are 1
30  float const R = .5f;
31  float Rb = R, Rt = Rb * ratio_Rt_Rb, H = 2 * R;
32 
33  // mesh of vertices (bottom and top) and normals
34  Vertices vb(slices), vt(slices), nbt(slices);
35  float const nz = (1 - Rt / Rb) * H;
36 
37  for (int s = 0; s < slices; ++s) {
38  float th = float(M_TWOPI * s / slices), st = sinf(th), ct = cosf(th);
39 
40  Vector3D vb_(Rb * ct, Rb * st, 0), vt_(Rt * ct, Rt * st, H);
41  vb[s] = vb_;
42  vt[s] = vt_;
43  if (smooth)
44  nbt[s] = Vector3D(vb_.x, vb_.y, nz).normalized();
45  }
46 
47  // make into triangles
48  int const nv = 6 * 2 * slices;
49  Vertices vs;
50  vs.reserve(nv);
51  Vertices ns;
52  if (smooth)
53  ns.reserve(nv);
54 
55  for (int s = 0; s < slices; ++s) {
56  int s1 = s, s2 = (s + 1) % slices;
57 
58  vs.addTriangle(vb.at(s1), Vector3D(0, 0, 0), vb.at(s2)); // bottom
59  if (smooth)
60  ns.addVertex(-Vector3D::_z, 3);
61 
62  vs.addTriangle(Vector3D(0, 0, H), vt.at(s1), vt.at(s2)); // top
63  if (smooth)
64  ns.addVertex(+Vector3D::_z, 3);
65 
66  vs.addQuad(vb.at(s1), vb.at(s2), vt.at(s2), vt.at(s1)); // side
67  if (smooth) {
68  auto &n1 = nbt.at(s1), &n2 = nbt.at(s2);
69  ns.addQuad(n1, n2, n2, n1);
70  }
71  }
72 
73  ASSERT(vs.count() == nv);
74  ASSERT(!smooth || ns.count() == nv);
75 
76  return makeMesh(vs, smooth ? &ns : nullptr);
77 }
static int const SLICES
Definition: geometry.h:90
static Vector3D const _z
Definition: def.h:46

References GUI::RealSpace::Vector3D::_z, GUI::RealSpace::Geometry::Vertices::addQuad(), GUI::RealSpace::Geometry::Vertices::addTriangle(), GUI::RealSpace::Geometry::Vertices::addVertex(), makeMesh(), GUI::RealSpace::Vector3D::normalized(), and SLICES.

Referenced by Geometry().

Here is the call graph for this function:

◆ meshDodecahedron()

Geometry::Mesh GUI::RealSpace::Geometry::meshDodecahedron ( )
staticprivate

Definition at line 22 of file dodecahedron.cpp.

23 {
24  const float GR = GoldenRatio, G1 = 1 / GR;
25 
26  Vertices vs_;
27  vs_.reserve(20);
28  for (float x : {-1, +1})
29  for (float y : {-1, +1})
30  for (float z : {-1, +1})
31  vs_.append(Vector3D(x, y, z));
32 
33  for (float g1 : {-G1, +G1})
34  for (float g : {-GR, +GR}) {
35  vs_.append(Vector3D(0, g1, g));
36  vs_.append(Vector3D(g1, g, 0));
37  vs_.append(Vector3D(g, 0, g1));
38  }
39 
40  ASSERT(20 == vs_.count());
41 
42  // scale to circumscribed sphere
43  float const F = .5f / vs_.at(0).length();
44  for (auto& v : vs_)
45  v = v * F;
46 
47  // face down
48  auto q = QQuaternion::rotationTo(-Vector3D::_z,
49  cross(vs_.at(8) - vs_.at(0), vs_.at(10) - vs_.at(0)));
50  for (int i = 0; i < 20; ++i) {
51  vs_[i] = q.rotatedVector(vs_.at(i));
52  vs_[i].z += 0.5f * std::sqrt(G1); // shift the bottom of the dodecahedron to z=0 plane
53  }
54 
55  Vertices vs;
56  vs.reserve(180);
57 
58  auto add5 = [&](unsigned i1, unsigned i2, unsigned i3, unsigned i4, unsigned i5) {
59  vs.addFan(vs_, {i1, i2, i3, i4, i5, i1});
60  };
61 
62  add5(1, 11, 17, 3, 16); // bottom
63  add5(1, 16, 10, 0, 9);
64  add5(16, 3, 12, 2, 10);
65  add5(3, 17, 7, 18, 12);
66  add5(17, 11, 5, 19, 7);
67  add5(11, 1, 9, 15, 5);
68 
69  add5(8, 4, 15, 9, 0);
70  add5(14, 8, 0, 10, 2);
71  add5(6, 14, 2, 12, 18);
72  add5(13, 6, 18, 7, 19);
73  add5(4, 13, 19, 5, 15);
74  add5(4, 8, 14, 6, 13); // top
75 
76  ASSERT(144 == vs.count());
77 
78  return makeMesh(vs);
79 }
const float GoldenRatio

References GUI::RealSpace::Vector3D::_z, GUI::RealSpace::Geometry::Vertices::addFan(), GUI::RealSpace::cross(), GUI::RealSpace::GoldenRatio, and makeMesh().

Referenced by Geometry().

Here is the call graph for this function:

◆ meshIcosahedron()

Geometry::Mesh GUI::RealSpace::Geometry::meshIcosahedron ( )
staticprivate

Definition at line 22 of file icosahedron.cpp.

23 {
24  Vertices vs_(12); // 12 vertices of the icosahedron retrieved from Icosahedron.cpp
25 
26  const float E = 1.0; // edge
27 
28  vs_[0] = Vector3D(-0.57735026918962573f * E, 0.0f * E, 0.0f);
29  vs_[1] = Vector3D(0.28867513459481281f * E, 0.5f * E, 0.0f);
30  vs_[2] = Vector3D(0.28867513459481281f * E, -0.5f * E, 0.0f);
31  vs_[3] = Vector3D(0.93417235896271578f * E, 0.0f * E, 0.57735026918962562f * E);
32  vs_[4] =
33  Vector3D(-0.46708617948135783f * E, 0.80901699437494756f * E, 0.57735026918962562f * E);
34  vs_[5] =
35  Vector3D(-0.46708617948135783f * E, -0.80901699437494756f * E, 0.57735026918962562f * E);
36  vs_[6] = Vector3D(-0.93417235896271578f * E, 0.0f * E, 0.93417235896271589f * E);
37  vs_[7] = Vector3D(0.46708617948135783f * E, 0.80901699437494756f * E, 0.93417235896271589f * E);
38  vs_[8] =
39  Vector3D(0.46708617948135783f * E, -0.80901699437494756f * E, 0.93417235896271589f * E);
40  vs_[9] = Vector3D(0.57735026918962573f * E, 0.0f * E, 1.5115226281523415f * E);
41  vs_[10] = Vector3D(-0.28867513459481281f * E, 0.5f * E, 1.5115226281523415f * E);
42  vs_[11] = Vector3D(-0.28867513459481281f * E, -0.5f * E, 1.5115226281523415f * E);
43 
44  ASSERT(12 == vs_.count());
45 
46  Vertices vs;
47  vs.reserve(60);
48 
49  // lower half of the icosahedron (clockwise ordering of vertices)
50  vs.addTriangle(vs_[0], vs_[1], vs_[2]);
51  vs.addTriangle(vs_[0], vs_[4], vs_[1]);
52  vs.addTriangle(vs_[1], vs_[3], vs_[2]);
53  vs.addTriangle(vs_[2], vs_[5], vs_[0]);
54 
55  vs.addTriangle(vs_[0], vs_[6], vs_[4]);
56  vs.addTriangle(vs_[4], vs_[7], vs_[1]);
57  vs.addTriangle(vs_[1], vs_[7], vs_[3]);
58  vs.addTriangle(vs_[3], vs_[8], vs_[2]);
59  vs.addTriangle(vs_[8], vs_[5], vs_[2]);
60  vs.addTriangle(vs_[5], vs_[6], vs_[0]);
61 
62  // upper half of the icosahedron (couter clockwise ordering of vertices)
63  vs.addTriangle(vs_[11], vs_[6], vs_[5]);
64  vs.addTriangle(vs_[8], vs_[11], vs_[5]);
65  vs.addTriangle(vs_[9], vs_[8], vs_[3]);
66  vs.addTriangle(vs_[9], vs_[3], vs_[7]);
67  vs.addTriangle(vs_[10], vs_[7], vs_[4]);
68  vs.addTriangle(vs_[6], vs_[10], vs_[4]);
69 
70  vs.addTriangle(vs_[10], vs_[6], vs_[11]);
71  vs.addTriangle(vs_[9], vs_[11], vs_[8]);
72  vs.addTriangle(vs_[9], vs_[7], vs_[10]);
73  vs.addTriangle(vs_[9], vs_[10], vs_[11]);
74 
75  ASSERT(60 == vs.count());
76 
77  return makeMesh(vs);
78 }

References GUI::RealSpace::Geometry::Vertices::addTriangle(), and makeMesh().

Referenced by Geometry().

Here is the call graph for this function:

◆ meshPlane()

Geometry::Mesh GUI::RealSpace::Geometry::meshPlane ( )
staticprivate

Definition at line 20 of file plane.cpp.

21 {
22  float const D = .5f;
23 
24  Vertices vs;
25  vs.reserve(4);
26  vs.addQuad({+D, +D, 0}, {-D, +D, 0}, {-D, -D, 0}, {+D, -D, 0});
27 
28  ASSERT(4 == vs.count());
29 
30  return makeMesh(vs);
31 }

References GUI::RealSpace::Geometry::Vertices::addQuad(), and makeMesh().

Referenced by Geometry().

Here is the call graph for this function:

◆ meshRipple()

Geometry::Mesh GUI::RealSpace::Geometry::meshRipple ( float  numSides,
float  ratio_asymmetry_W 
)
staticprivate

Definition at line 21 of file ripple.cpp.

22 {
23  int const sides = qRound(numSides);
24  bool const smooth = (0 == sides); // sides = 0 implies smooth -> e.g. cosine ripple
25  int const slices = smooth ? 4 * SLICES : sides;
26 
27  // Values are chosen such that length, width and height are 1
28  float const R = .5f;
29  float const H = 2 * R; // L = W = H = 2*R
30  float const asymmetry = ratio_asymmetry_W * 2 * R; // for CosineRipple asymmetry is inherently 0
31 
32  Vertices vfront(slices), vback(slices);
33 
34  if (numSides == 3) {
35  // SawtoothRipple: saw-tooth (3 rectangular sides and 2 triangular front and back)
36  vfront[0] = Vector3D(-R, -R, 0);
37  vfront[1] = Vector3D(-R, asymmetry, H);
38  vfront[2] = Vector3D(-R, R, 0);
39 
40  vback[0] = Vector3D(R, -R, 0);
41  vback[1] = Vector3D(R, asymmetry, H);
42  vback[2] = Vector3D(R, R, 0);
43  } else if (numSides == 0) {
44  // CosineRipple: cosine ripple
45  for (int s = 0; s < slices; ++s) {
46  auto th = static_cast<float>(M_PI * s / (slices + 1));
47  float y = -R * cosf(th);
48  float z = R * (1.0f + cosf(2 * static_cast<float>(M_PI) * y / (2 * R)));
49  vfront[s] = Vector3D(-R, y, z);
50  vback[s] = Vector3D(R, y, z);
51  }
52  }
53 
54  int const nv = (3 + 3 + 6) * slices; // 3 for part of front face, 3 for part of back face
55  // 6 for side face
56 
57  Vertices vs;
58  vs.reserve(nv);
59 
60  for (int s = 0; s < slices; ++s) {
61  int s1 = s, s2 = (s + 1) % slices;
62 
63  // clockwise ordering of vertices
64  vs.addTriangle(vfront.at(s1), vfront.at(s2), Vector3D(-R, asymmetry, H / 2)); // front
65 
66  // counter-clockwise ordering of vertices
67  vs.addTriangle(vback.at(s1), Vector3D(R, asymmetry, H / 2), vback.at(s2)); // back
68 
69  // counter-clockwise ordering of vertices
70  vs.addQuad(vfront.at(s2), vfront.at(s1), vback.at(s1), vback.at(s2)); // side
71  }
72 
73  ASSERT(vs.count() == nv);
74 
75  return makeMesh(vs, nullptr); // normals not calculated here and left for makeMesh to calculate
76 }

References GUI::RealSpace::Geometry::Vertices::addQuad(), GUI::RealSpace::Geometry::Vertices::addTriangle(), makeMesh(), and SLICES.

Referenced by Geometry().

Here is the call graph for this function:

◆ meshSphere()

Geometry::Mesh GUI::RealSpace::Geometry::meshSphere ( float  cut,
float  baseShift = 0.0f,
float  removedTop = 0.0f 
)
staticprivate

Definition at line 24 of file sphere.cpp.

25 {
26  if (1 <= cut)
27  return Mesh();
28  cut = qMax(0.f, cut);
29  ASSERT(0 <= cut && cut < 1);
30 
31  // 'rings' are the # of horizontal cross-sections ranging from bottom to top of the sphere
32  // 'slices' are the # of vertices in a given ring
33  int rings;
34  int slices = SLICES;
35  float minPh, maxPh, phRge;
36 
37  if (cut > 0) // South pole absent
38  {
39  minPh = asinf(2 * cut - 1);
40  if (removedTop > 0) // North pole absent
41  maxPh = asinf(1 - 2 * removedTop);
42  else // North pole present
43  maxPh = float(M_PI_2) - float(M_PI) / RINGS;
44  } else // South pole present
45  {
46  minPh = -float(M_PI_2) + float(M_PI) / RINGS;
47  if (removedTop > 0) // North pole absent
48  maxPh = asinf(1 - removedTop);
49  else // North pole present
50  maxPh = float(M_PI_2) - float(M_PI) / RINGS;
51  }
52  phRge = maxPh - minPh;
53  rings = qMax(2, qCeil(qreal(RINGS * phRge) / M_PI)); // At least 2 rings (incl. lowest ring)
54 
55  ASSERT(qAbs(minPh) < float(M_PI_2));
56  ASSERT(2 <= rings && 2 <= slices);
57 
58  // meshes of vertices and normals, without poles, _[ring][slice]
59  QVector<Vertices> vs_(rings);
60  QVector<Vertices> ns_(rings);
61  for (auto& ring : vs_)
62  ring.resize(slices);
63  for (auto& ring : ns_)
64  ring.resize(slices);
65 
66  float const R = .5f;
67 
68  for (int r = 0; r < rings; ++r) {
69  float ph = minPh + phRge * r / (rings - 1);
70  float cp = cosf(ph), sp = sinf(ph);
71 
72  for (int s = 0; s < slices; ++s) {
73  auto th = float(M_TWOPI * s / slices);
74  Vector3D v(R * cp * cosf(th), R * cp * sinf(th), R * sp);
75  v.z += baseShift; // baseShift is used for shifting the bottom of the spherical shape
76  // to z=0 plane
77  vs_[r][s] = v;
78  ns_[r][s] = v.normalized();
79  }
80  }
81 
82  // make into triangles
83  int const nv = 6 * (rings)*slices;
84  Vertices vs;
85  vs.reserve(nv);
86  Vertices ns;
87  ns.reserve(nv);
88 
89  for (int r = 0; r < rings; ++r) {
90  auto &vr = vs_.at(r), &nr = ns_.at(r);
91 
92  for (int s = 0; s < slices; ++s) {
93  int s0 = s, s1 = (s + 1) % slices;
94 
95  auto &v0 = vr.at(s0), &v1 = vr.at(s1);
96  auto &n0 = nr.at(s0), &n1 = nr.at(s1);
97 
98  if (r == 0) { // bottom most ring
99  Vector3D vp, n0, n1, np(-Vector3D::_z);
100  if (cut > 0) { // South pole absent
101  vp = Vector3D(0, 0, v0.z);
102  n0 = n1 = np;
103  } else { // South pole present
104  vp = Vector3D(0, 0, -R + baseShift);
105  n0 = nr.at(s0);
106  n1 = nr.at(s1);
107  }
108  vs.addTriangle(v0, vp, v1);
109  ns.addTriangle(n0, np, n1);
110  }
111 
112  if (r + 1 == rings) { // top most ring
113  Vector3D vp, n0, n1, np(Vector3D::_z);
114  if (removedTop > 0) { // North pole absent
115  vp = Vector3D(0, 0, v0.z);
116  n0 = n1 = np;
117  } else { // North pole present
118  vp = Vector3D(0, 0, +R + baseShift);
119  n0 = nr.at(s0);
120  n1 = nr.at(s1);
121  }
122  vs.addTriangle(v0, v1, vp);
123  ns.addTriangle(n0, n1, np);
124  } else { // in between poles
125  auto &vr1 = vs_.at(r + 1), &nr1 = ns_.at(r + 1);
126  auto &n2 = nr1.at(s1), &n3 = nr1.at(s0);
127  vs.addQuad(v0, v1, vr1.at(s1), vr1.at(s0));
128  ns.addQuad(n0, n1, n2, n3);
129  }
130  }
131  }
132 
133  return makeMesh(vs, ns);
134 }
static int const RINGS
Definition: geometry.h:90

References GUI::RealSpace::Vector3D::_z, GUI::RealSpace::Geometry::Vertices::addQuad(), GUI::RealSpace::Geometry::Vertices::addTriangle(), makeMesh(), GUI::RealSpace::Vector3D::normalized(), RINGS, SLICES, and GUI::RealSpace::Vector3D::z.

Referenced by Geometry().

Here is the call graph for this function:

◆ meshTruncBox()

Geometry::Mesh GUI::RealSpace::Geometry::meshTruncBox ( float  tD)
staticprivate

Definition at line 20 of file truncbox.cpp.

21 { // t/D
22  if (tD <= 0)
23  return meshBox();
24 
25  float const D = .5f, t = D * (1 - qMin(tD, 1.f));
26  Vertices vs;
27  vs.reserve(150);
28 
29  QVector<float> as({+D, +t, -t, -D, -D, -t, +t, +D});
30  QVector<float> bs({+t, +D, +D, +t, -t, -D, -D, -t});
31 
32  auto side = [&](int ax, int ay, int az, int bx, int by, int bz, const Vector3D& d, bool rev) {
33  Vertices vs_(8);
34  for (int i = 0; i < 8; ++i)
35  vs_[rev ? 7 - i : i] =
36  Vector3D(ax * as.at(i) + bx * bs.at(i), ay * as.at(i) + by * bs.at(i),
37  az * as.at(i) + bz * bs.at(i))
38  + d;
39  vs.addFan(vs_, {0, 1, 2, 3, 4, 5, 6, 7, 0});
40  };
41 
42  // +0.5f is required to shift the bottom of the Truncated Box to the z=0 plane
43 
44  auto corner = [&](int x, int y, int z) {
45  Vertices vs_({{D * x, D * y, t * z + 0.5f},
46  {D * x, t * y, D * z + 0.5f},
47  {t * x, D * y, D * z + 0.5f}});
48  if (x * y * z > 0)
49  vs.addTriangle(vs_.at(0), vs_.at(2), vs_.at(1));
50  else
51  vs.addTriangle(vs_.at(0), vs_.at(1), vs_.at(2));
52  };
53 
54  side(0, 1, 0, 0, 0, 1, Vector3D(+D, 0, +0.5f), false);
55  side(0, 1, 0, 0, 0, 1, Vector3D(-D, 0, +0.5f), true);
56  side(1, 0, 0, 0, 0, 1, Vector3D(0, +D, +0.5f), true);
57  side(1, 0, 0, 0, 0, 1, Vector3D(0, -D, +0.5f), false);
58  side(1, 0, 0, 0, 1, 0, Vector3D(0, 0, +D + 0.5f), false);
59  side(1, 0, 0, 0, 1, 0, Vector3D(0, 0, -D + 0.5f), true);
60 
61  for (int x : {-1, +1})
62  for (int y : {-1, +1})
63  for (int z : {-1, +1})
64  corner(x, y, z);
65 
66  ASSERT(150 == vs.count());
67 
68  return makeMesh(vs);
69 }

References GUI::RealSpace::Geometry::Vertices::addTriangle(), makeMesh(), and meshBox().

Referenced by Geometry().

Here is the call graph for this function:

Friends And Related Function Documentation

◆ Buffer

friend class Buffer
friend

Definition at line 30 of file geometry.h.

◆ GeometryStore

friend class GeometryStore
friend

Definition at line 31 of file geometry.h.

Member Data Documentation

◆ m_key

GeometricID::Key GUI::RealSpace::Geometry::m_key
private

Definition at line 72 of file geometry.h.

Referenced by Geometry(), and GUI::RealSpace::GeometryStore::geometryDeleted().

◆ m_mesh

Mesh GUI::RealSpace::Geometry::m_mesh
private

Definition at line 74 of file geometry.h.

Referenced by GUI::RealSpace::Buffer::Buffer(), and Geometry().

◆ RINGS

int const GUI::RealSpace::Geometry::RINGS = 12
staticprivate

Definition at line 90 of file geometry.h.

Referenced by meshSphere().

◆ SLICES

int const GUI::RealSpace::Geometry::SLICES = 24
staticprivate

Definition at line 90 of file geometry.h.

Referenced by meshColumn(), meshRipple(), and meshSphere().


The documentation for this class was generated from the following files: