Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
GeometrySimple.cc
Go to the documentation of this file.
1#include <algorithm>
2#include <iostream>
3
5
6namespace Garfield {
7
9
10void GeometrySimple::AddSolid(Solid* solid, Medium* medium) {
11 // Make sure the solid and the medium are defined.
12 if (!solid || !medium) {
13 std::cerr << m_className << "::AddSolid: Null pointer.\n";
14 return;
15 }
16
17 // Update the bounding box ranges
18 double xmin, ymin, zmin;
19 double xmax, ymax, zmax;
20 if (!solid->GetBoundingBox(xmin, ymin, zmin, xmax, ymax, zmax)) {
21 std::cerr << m_className << "::AddSolid: Solid has no bounding box.\n";
22 return;
23 }
24
25 if (m_hasBoundingBox) {
26 m_bbMin[0] = std::min(m_bbMin[0], xmin);
27 m_bbMin[1] = std::min(m_bbMin[1], ymin);
28 m_bbMin[2] = std::min(m_bbMin[2], zmin);
29 m_bbMax[0] = std::max(m_bbMax[0], xmax);
30 m_bbMax[1] = std::max(m_bbMax[1], ymax);
31 m_bbMax[2] = std::max(m_bbMax[2], zmax);
32 } else {
33 m_bbMin[0] = xmin;
34 m_bbMin[1] = ymin;
35 m_bbMin[2] = zmin;
36 m_bbMax[0] = xmax;
37 m_bbMax[1] = ymax;
38 m_bbMax[2] = zmax;
39 m_hasBoundingBox = true;
40 }
41
42 // Add the new solid to the list.
43 m_solids.emplace_back(std::make_pair(solid, medium));
44}
45
46Solid* GeometrySimple::GetSolid(const double x, const double y,
47 const double z, const bool tesselated) const {
48 for (const auto& solid : m_solids) {
49 if (solid.first->IsInside(x, y, z, tesselated)) return solid.first;
50 }
51 return nullptr;
52}
53
55 const double x, const double y, const double z,
56 const bool tesselated) const {
57 for (const auto& solid : m_solids) {
58 if (solid.first->IsInside(x, y, z, tesselated)) {
59 return solid.second;
60 }
61 }
62 return m_medium;
63}
64
65Solid* GeometrySimple::GetSolid(const size_t i) const {
66 if (i >= m_solids.size()) {
67 std::cerr << m_className << "::GetSolid: Index out of range.\n";
68 return nullptr;
69 }
70 return m_solids[i].first;
71}
72
73Solid* GeometrySimple::GetSolid(const size_t i, Medium*& medium) const {
74 if (i >= m_solids.size()) {
75 std::cerr << m_className << "::GetSolid: Index out of range.\n";
76 return nullptr;
77 }
78 medium = m_solids[i].second;
79 return m_solids[i].first;
80}
81
83 m_solids.clear();
84 m_medium = nullptr;
85}
86
88 std::cout << m_className << "::PrintSolids:\n";
89 const auto nSolids = m_solids.size();
90 if (nSolids == 1) {
91 std::cout << " 1 solid\n";
92 } else {
93 std::cout << " " << nSolids << " solids\n";
94 }
95 if (m_solids.empty()) return;
96 std::cout << " Index Type Medium\n";
97 for (size_t i = 0; i < nSolids; ++i) {
98 std::cout << " " << i << " ";
99 if (m_solids[i].first->IsBox()) {
100 std::cout << "box ";
101 } else if (m_solids[i].first->IsTube()) {
102 std::cout << "tube ";
103 } else if (m_solids[i].first->IsSphere()) {
104 std::cout << "sphere ";
105 } else if (m_solids[i].first->IsHole()) {
106 std::cout << "hole ";
107 } else if (m_solids[i].first->IsRidge()) {
108 std::cout << "ridge ";
109 } else if (m_solids[i].first->IsExtrusion()) {
110 std::cout << "extrusion ";
111 } else if (m_solids[i].first->IsWire()) {
112 std::cout << "wire ";
113 } else {
114 std::cout << "unknown ";
115 }
116 if (m_solids[i].second) {
117 std::cout << m_solids[i].second->GetName() << "\n";
118 } else {
119 std::cout << " ---\n";
120 }
121 }
122}
123
124bool GeometrySimple::IsInside(const double x, const double y,
125 const double z, const bool tesselated) const {
126 if (!IsInBoundingBox(x, y, z)) return false;
127
128 for (const auto& solid : m_solids) {
129 if (solid.first->IsInside(x, y, z, tesselated)) return true;
130 }
131 return false;
132}
133
134bool GeometrySimple::IsInBoundingBox(const double x, const double y,
135 const double z) const {
136 if (!m_hasBoundingBox) {
137 if (m_debug) {
138 std::cerr << m_className << "::IsInBoundingBox:\n"
139 << " Bounding box is not defined.\n";
140 }
141 return true;
142 }
143
144 if (x >= m_bbMin[0] && x <= m_bbMax[0] &&
145 y >= m_bbMin[1] && y <= m_bbMax[1] &&
146 z >= m_bbMin[2] && z <= m_bbMax[2])
147 return true;
148 return false;
149}
150}
bool IsInside(const double x, const double y, const double z, const bool tesselated=false) const override
Check if a point is inside the geometry.
Medium * m_medium
Background medium.
std::array< double, 3 > m_bbMin
Medium * GetMedium(const double x, const double y, const double z, const bool tesselated=false) const override
Retrieve the medium at a given point.
std::array< double, 3 > m_bbMax
std::vector< std::pair< Solid *, Medium * > > m_solids
List of solids and associated media.
bool IsInBoundingBox(const double x, const double y, const double z) const
Determine whether a point is inside the envelope of the geometry.
Solid * GetSolid(const size_t i) const override
Get a solid from the list.
void Clear()
Reset the geometry.
void PrintSolids()
Print a summary of the solids present in the geometry.
bool m_debug
Switch on/off debugging messages.
void AddSolid(Solid *s, Medium *m)
Add a solid to the geometry, together with the medium inside.
GeometrySimple()
Constructor.
Abstract base class for geometry classes.
Definition: Geometry.hh:13
std::string m_className
Definition: Geometry.hh:44
Abstract base class for media.
Definition: Medium.hh:13
Abstract base class for solids.
Definition: Solid.hh:28
virtual bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const =0
Return the bounding box of the solid.