8#include <TGeoBoolNode.h>
9#include <TGeoCompositeShape.h>
29 std::cerr <<
m_className <<
"::SetGeometry: Null pointer.\n";
47 std::cerr <<
m_className <<
"::Plot3d: Geometry is not defined.\n";
53 std::cerr <<
m_className <<
"::Plot3d: Geometry is empty.\n";
58 double xMin = 0., yMin = 0., zMin = 0.;
59 double xMax = 0., yMax = 0., zMax = 0.;
60 if (!m_geometry->
GetBoundingBox(xMin, yMin, zMin, xMax, yMax, zMax)) {
61 std::cerr <<
m_className <<
"::Plot3d: Cannot retrieve bounding box.\n";
66 gGeoManager =
nullptr;
67 m_geoManager.reset(
new TGeoManager(
"ViewGeometryGeoManager",
""));
68 TGeoMaterial* matVacuum =
new TGeoMaterial(
"Vacuum", 0., 0., 0.);
69 TGeoMedium* medVacuum =
new TGeoMedium(
"Vacuum", 1, matVacuum);
70 m_media.push_back(medVacuum);
72 TGeoMaterial* matDefault =
new TGeoMaterial(
"Default", 28.085, 14., 2.329);
73 TGeoMedium* medDefault =
new TGeoMedium(
"Default", 1, matDefault);
74 TGeoVolume* world = m_geoManager->MakeBox(
75 "World", medVacuum, std::max(fabs(xMin), fabs(xMax)),
76 std::max(fabs(yMin), fabs(yMax)), std::max(fabs(zMin), fabs(zMax)));
77 m_geoManager->SetTopVolume(world);
78 m_volumes.push_back(world);
80 for (
unsigned int i = 0; i < nSolids; ++i) {
84 <<
" Could not get solid " << i <<
" from geometry.\n";
88 double x0 = 0., y0 = 0., z0 = 0.;
90 std::cerr <<
m_className <<
"::Plot3d: Could not determine solid centre.\n";
94 double ctheta = 1., stheta = 0.;
95 double cphi = 1., sphi = 0.;
98 <<
" Could not determine solid orientation.\n";
101 double matrix[9] = {cphi * ctheta, -sphi, cphi * stheta,
102 sphi * ctheta, cphi, sphi * stheta,
104 TGeoVolume* volume =
nullptr;
108 volume = m_geoManager->MakeTube(
"Tube", medDefault, 0., rt, lz);
109 }
else if (solid->
IsWire()) {
112 volume = m_geoManager->MakeTube(
"Wire", medDefault, 0., rw, lz);
113 }
else if (solid->
IsBox()) {
117 volume = m_geoManager->MakeBox(
"Box", medDefault, dx, dy, dz);
121 volume = m_geoManager->MakeSphere(
"Sphere", medDefault, rmin, rmax);
122 }
else if (solid->
IsHole()) {
128 const double lz = 10 * std::max({dx, dy, dz});
129 const double rm = 0.5 * (r1 + r2);
130 const double dr = 0.5 * (r2 - r1) * lz / dz;
131 TGeoBBox* box =
new TGeoBBox(
"HoleBox", dx, dy, dz);
132 TGeoCone* cone =
new TGeoCone(
"HoleCone", lz, 0, rm - dr, 0, rm + dr);
133 TGeoCompositeShape* hole =
new TGeoCompositeShape(
"Hole",
134 new TGeoSubtraction(box, cone));
135 hole->RegisterYourself();
136 volume =
new TGeoVolume(
"Hole", hole, medDefault);
142 volume = m_geoManager->MakeArb8(
"Ridge", medDefault, dz);
143 auto arb = (TGeoArb8*)volume->GetShape();
144 arb->SetVertex(0, -dx, -dy);
145 arb->SetVertex(1, -dx, +dy);
146 arb->SetVertex(2, +dx, +dy);
147 arb->SetVertex(3, +dx, -dy);
148 arb->SetVertex(4, xr, -dy);
149 arb->SetVertex(5, xr, +dy);
150 arb->SetVertex(6, xr, +dy);
151 arb->SetVertex(7, xr, -dy);
155 std::vector<double> xp;
156 std::vector<double> yp;
158 volume = m_geoManager->MakeXtru(
"Extrusion", medDefault, 2);
159 auto xtru = (TGeoXtru*)volume->GetShape();
160 xtru->DefinePolygon(xp.size(), xp.data(), yp.data());
161 xtru->DefineSection(0, -dz);
162 xtru->DefineSection(1, +dz);
164 std::cerr <<
m_className <<
"::Plot3d: Unknown type of solid.\n";
169 volume->SetLineColor(solid->
GetColour());
170 }
else if (!medium) {
171 volume->SetLineColor(kGreen + 2);
172 volume->SetTransparency(50);
173 }
else if (medium->
IsGas()) {
174 volume->SetLineColor(kBlue + medium->
GetId());
175 volume->SetTransparency(50);
177 volume->SetLineColor(kRed + medium->
GetId());
178 volume->SetTransparency(50);
180 volume->SetLineColor(kViolet + medium->
GetId());
181 volume->SetTransparency(0);
185 TGeoTranslation t(x0, y0, z0);
186 TGeoCombiTrans* transform =
new TGeoCombiTrans(t, r);
187 m_volumes.push_back(volume);
188 m_geoManager->GetTopVolume()->AddNode(volume, 1, transform);
190 m_geoManager->CloseGeometry();
191 m_geoManager->GetTopNode()->Draw(
"ogl");
197 std::cerr <<
m_className <<
"::Plot2d: Geometry is not defined.\n";
203 std::cerr <<
m_className <<
"::Plot2d: Geometry is empty.\n";
208 double x0 = 0., y0 = 0.;
209 double x1 = 0., y1 = 0.;
218 std::array<double, 3> bbmin;
219 std::array<double, 3> bbmax;
221 bbmax[0], bbmax[1], bbmax[2])) {
222 std::cerr <<
m_className <<
"::Plot2d: Cannot retrieve bounding box.\n";
230 canvas->SetTitle(
"Geometry");
234 (gPad->GetListOfPrimitives()->GetSize() == 0 && gPad->GetX1() == 0 &&
235 gPad->GetX2() == 1 && gPad->GetY1() == 0 && gPad->GetY2() == 1)) {
238 const double bm = canvas->GetBottomMargin();
239 const double lm = canvas->GetLeftMargin();
240 const double rm = canvas->GetRightMargin();
241 const double tm = canvas->GetTopMargin();
243 TPad* pad =
new TPad(
"geo",
"", 0, 0, 1, 1);
244 pad->SetFillStyle(0);
245 pad->SetFrameFillStyle(0);
249 gPad->Range(x0 - (x1 - x0) * (lm / (1. - rm - lm)),
250 y0 - (y1 - y0) * (bm / (1. - tm - lm)),
251 x1 + (x1 - x0) * (rm / (1. - rm - lm)),
252 y1 + (y1 - y0) * (tm / (1. - tm - lm)));
255 for (
unsigned int i = 0; i < nSolids; ++i) {
256 auto solid = m_geometry->
GetSolid(i);
257 if (!solid)
continue;
258 std::vector<Panel> panels;
261 for (
const auto& panel : panels) {
262 const unsigned int nv = panel.xv.size();
263 if (nv < 3)
continue;
264 std::vector<double> xpl;
265 std::vector<double> ypl;
266 for (
unsigned int j = 0; j < nv; ++j) {
268 ToPlane(panel.xv[j], panel.yv[j], panel.zv[j], u, v);
272 xpl.push_back(xpl[0]);
273 ypl.push_back(ypl[0]);
274 if (panel.colour < 0) {
275 pl.SetLineColor(kBlack);
277 pl.SetLineColor(panel.colour);
279 pl.DrawPolyLine(nv + 1, xpl.data(), ypl.data(),
"same");
285void ViewGeometry::Reset() {
286 for (
auto it = m_volumes.begin(), end = m_volumes.end(); it != end; ++it) {
288 TGeoShape* shape = (*it)->GetShape();
289 if (shape)
delete shape;
294 for (
auto it = m_media.begin(), end = m_media.end(); it != end; ++it) {
296 TGeoMaterial* material = (*it)->GetMaterial();
297 if (material)
delete material;
303 m_geoManager.reset(
nullptr);
"Native" geometry, using simple shapes.
size_t GetNumberOfSolids() const override
Return the number of solids in the geometry.
Medium * GetMedium(const double x, const double y, const double z, const bool tesselated=false) const override
Retrieve the medium at a given point.
Solid * GetSolid(const size_t i) const override
Get a solid from the list.
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
Get the bounding box (envelope of the geometry).
Abstract base class for media.
int GetId() const
Return the id number of the class instance.
virtual bool IsSemiconductor() const
Is this medium a semiconductor?
virtual bool IsGas() const
Is this medium a gas?
Abstract base class for solids.
virtual double GetUpperRadius() const
Return the upper radius (of a hole).
virtual bool IsTube() const
Return true if the solid is a tube.
virtual bool IsRidge() const
Return true if the solid is a ridge.
virtual double GetHalfLengthX() const
Return the half-length along x.
virtual bool IsHole() const
Return true if the solid is a hole.
virtual double GetHalfLengthZ() const
Return the half-length along z.
virtual bool IsBox() const
Return true if the solid is a box.
virtual double GetHalfLengthY() const
Return the half-length along y.
virtual bool IsExtrusion() const
Return true if the solid is an extrusion.
bool GetCentre(double &x, double &y, double &z) const
Retrieve the centre point of the solid.
virtual bool GetProfile(std::vector< double > &xv, std::vector< double > &yv) const
Get the vertices defining an extrusion.
virtual double GetRidgeOffset() const
Return the x-offset of a ridge.
virtual double GetLowerRadius() const
Return the lower radius (of a hole).
virtual void Cut(const double x0, const double y0, const double z0, const double xn, const double yn, const double zn, std::vector< Panel > &panels)=0
virtual double GetOuterRadius() const
Return the outer radius.
bool GetOrientation(double &ctheta, double &stheta, double &cphi, double &sphi) const
Retrieve the orientation (azimuthal and polar angles) of the solid.
virtual bool IsWire() const
Return true if the solid is a wire.
int GetColour() const
Get the colour of the solid.
virtual double GetRadius() const
Return the radius.
virtual bool IsSphere() const
Return true if the solid is a sphere.
virtual double GetInnerRadius() const
Return the inner radius.
virtual double GetRidgeHeight() const
Return the height of a ridge.
Base class for visualization classes.
std::array< double, 4 > m_plane
std::array< std::array< double, 3 >, 3 > m_proj
TPad * GetCanvas()
Retrieve the canvas.
bool PlotLimits(Sensor *sensor, double &xmin, double &ymin, double &xmax, double &ymax) const
void ToPlane(const T x, const T y, const T z, T &xp, T &yp) const
bool PlotLimitsFromUserBox(double &xmin, double &ymin, double &xmax, double &ymax) const
void Plot3d()
Draw a three-dimensional view of the geometry.
void SetGeometry(GeometrySimple *geo)
Set the geometry to be drawn.
~ViewGeometry()
Destructor.
void Plot(const bool twod=false)
Draw the geometry.
void Plot2d()
Draw a cut through the geometry at the current viewing plane.
ViewGeometry()
Constructor.