48 std::cerr <<
m_className <<
"::Plot3d: Geometry is not defined.\n";
54 std::cerr <<
m_className <<
"::Plot3d: Geometry is empty.\n";
59 double xMin = 0., yMin = 0., zMin = 0.;
60 double xMax = 0., yMax = 0., zMax = 0.;
61 if (!m_geometry->GetBoundingBox(xMin, yMin, zMin, xMax, yMax, zMax)) {
62 std::cerr <<
m_className <<
"::Plot3d: Cannot retrieve bounding box.\n";
67 gGeoManager =
nullptr;
68 m_geoManager.reset(
new TGeoManager(
"ViewGeometryGeoManager",
""));
69 TGeoMaterial* matVacuum =
new TGeoMaterial(
"Vacuum", 0., 0., 0.);
70 TGeoMedium* medVacuum =
new TGeoMedium(
"Vacuum", 1, matVacuum);
71 m_media.push_back(medVacuum);
73 TGeoMaterial* matDefault =
new TGeoMaterial(
"Default", 28.085, 14., 2.329);
74 TGeoMedium* medDefault =
new TGeoMedium(
"Default", 1, matDefault);
75 TGeoVolume* world = m_geoManager->MakeBox(
76 "World", medVacuum, std::max(fabs(xMin), fabs(xMax)),
77 std::max(fabs(yMin), fabs(yMax)), std::max(fabs(zMin), fabs(zMax)));
78 m_geoManager->SetTopVolume(world);
79 m_volumes.push_back(world);
81 for (
size_t i = 0; i < nSolids; ++i) {
82 auto solid = m_geometry->GetSolid(i);
85 <<
" Could not get solid " << i <<
" from geometry.\n";
89 double x0 = 0., y0 = 0., z0 = 0.;
90 if (!solid->GetCentre(x0, y0, z0)) {
91 std::cerr <<
m_className <<
"::Plot3d: Could not determine solid centre.\n";
95 double ctheta = 1., stheta = 0.;
96 double cphi = 1., sphi = 0.;
97 if (!solid->GetOrientation(ctheta, stheta, cphi, sphi)) {
99 <<
" Could not determine solid orientation.\n";
102 double matrix[9] = {cphi * ctheta, -sphi, cphi * stheta,
103 sphi * ctheta, cphi, sphi * stheta,
105 TGeoVolume* volume =
nullptr;
106 if (solid->IsTube()) {
107 const double rt = solid->GetRadius();
108 const double lz = solid->GetHalfLengthZ();
109 volume = m_geoManager->MakeTube(
"Tube", medDefault, 0., rt, lz);
110 }
else if (solid->IsWire()) {
111 const double rw = solid->GetRadius();
112 const double lz = solid->GetHalfLengthZ();
113 volume = m_geoManager->MakeTube(
"Wire", medDefault, 0., rw, lz);
114 }
else if (solid->IsBox()) {
115 const double dx = solid->GetHalfLengthX();
116 const double dy = solid->GetHalfLengthY();
117 const double dz = solid->GetHalfLengthZ();
118 volume = m_geoManager->MakeBox(
"Box", medDefault, dx, dy, dz);
119 }
else if (solid->IsSphere()) {
120 const double rmin = std::max(solid->GetInnerRadius(), 0.);
121 const double rmax = solid->GetOuterRadius();
122 volume = m_geoManager->MakeSphere(
"Sphere", medDefault, rmin, rmax);
123 }
else if (solid->IsHole()) {
124 const double r1 = solid->GetLowerRadius();
125 const double r2 = solid->GetUpperRadius();
126 const double dx = solid->GetHalfLengthX();
127 const double dy = solid->GetHalfLengthY();
128 const double dz = solid->GetHalfLengthZ();
129 const double lz = 10 * std::max({dx, dy, dz});
130 const double rm = 0.5 * (r1 + r2);
131 const double dr = 0.5 * (r2 - r1) * lz / dz;
132 TGeoBBox* box =
new TGeoBBox(
"HoleBox", dx, dy, dz);
133 TGeoCone* cone =
new TGeoCone(
"HoleCone", lz, 0, rm - dr, 0, rm + dr);
134 TGeoCompositeShape* hole =
new TGeoCompositeShape(
"Hole",
135 new TGeoSubtraction(box, cone));
136 hole->RegisterYourself();
137 volume =
new TGeoVolume(
"Hole", hole, medDefault);
138 }
else if (solid->IsRidge()) {
139 const double dx = solid->GetHalfLengthX();
140 const double dy = solid->GetHalfLengthY();
141 const double dz = 0.5 * solid->GetRidgeHeight();
142 const double xr = solid->GetRidgeOffset();
143 volume = m_geoManager->MakeArb8(
"Ridge", medDefault, dz);
144 auto arb = (TGeoArb8*)volume->GetShape();
145 arb->SetVertex(0, -dx, -dy);
146 arb->SetVertex(1, -dx, +dy);
147 arb->SetVertex(2, +dx, +dy);
148 arb->SetVertex(3, +dx, -dy);
149 arb->SetVertex(4, xr, -dy);
150 arb->SetVertex(5, xr, +dy);
151 arb->SetVertex(6, xr, +dy);
152 arb->SetVertex(7, xr, -dy);
154 }
else if (solid->IsExtrusion()) {
155 const double dz = solid->GetHalfLengthZ();
156 std::vector<double> xp;
157 std::vector<double> yp;
158 if (!solid->GetProfile(xp, yp))
continue;
159 volume = m_geoManager->MakeXtru(
"Extrusion", medDefault, 2);
160 auto xtru = (TGeoXtru*)volume->GetShape();
161 xtru->DefinePolygon(xp.size(), xp.data(), yp.data());
162 xtru->DefineSection(0, -dz);
163 xtru->DefineSection(1, +dz);
165 std::cerr <<
m_className <<
"::Plot3d: Unknown type of solid.\n";
168 Medium* medium = m_geometry->GetMedium(x0, y0, z0);
169 if (solid->GetColour() >= 0) {
170 volume->SetLineColor(solid->GetColour());
171 }
else if (!medium) {
172 volume->SetLineColor(kGreen + 2);
173 volume->SetTransparency(50);
174 }
else if (medium->
IsGas()) {
175 volume->SetLineColor(kBlue + medium->
GetId());
176 volume->SetTransparency(50);
178 volume->SetLineColor(kRed + medium->
GetId());
179 volume->SetTransparency(50);
181 volume->SetLineColor(kViolet + medium->
GetId());
182 volume->SetTransparency(0);
186 TGeoTranslation t(x0, y0, z0);
187 TGeoCombiTrans* transform =
new TGeoCombiTrans(t, r);
188 m_volumes.push_back(volume);
189 m_geoManager->GetTopVolume()->AddNode(volume, 1, transform);
191 m_geoManager->CloseGeometry();
192 m_geoManager->GetTopNode()->Draw(
"gl");
198 std::cerr <<
m_className <<
"::Plot2d: Geometry is not defined.\n";
202 const auto nSolids = m_geometry->GetNumberOfSolids();
204 std::cerr <<
m_className <<
"::Plot2d: Geometry is empty.\n";
209 double x0 = 0., y0 = 0.;
210 double x1 = 0., y1 = 0.;
219 std::array<double, 3> bbmin;
220 std::array<double, 3> bbmax;
221 if (!m_geometry->GetBoundingBox(bbmin[0], bbmin[1], bbmin[2],
222 bbmax[0], bbmax[1], bbmax[2])) {
223 std::cerr <<
m_className <<
"::Plot2d: Cannot retrieve bounding box.\n";
231 canvas->SetTitle(
"Geometry");
234 const double bm = canvas->GetBottomMargin();
235 const double lm = canvas->GetLeftMargin();
236 const double rm = canvas->GetRightMargin();
237 const double tm = canvas->GetTopMargin();
239 TPad* pad =
new TPad(
"geo",
"", 0, 0, 1, 1);
240 pad->SetFillStyle(0);
241 pad->SetFrameFillStyle(0);
245 gPad->Range(x0 - (x1 - x0) * (lm / (1. - rm - lm)),
246 y0 - (y1 - y0) * (bm / (1. - tm - lm)),
247 x1 + (x1 - x0) * (rm / (1. - rm - lm)),
248 y1 + (y1 - y0) * (tm / (1. - tm - lm)));
251 for (
size_t i = 0; i < nSolids; ++i) {
252 auto solid = m_geometry->GetSolid(i);
253 if (!solid)
continue;
254 std::vector<Panel> panels;
257 for (
const auto& panel : panels) {
258 const auto nv = panel.xv.size();
259 if (nv < 3)
continue;
260 std::vector<double> xpl;
261 std::vector<double> ypl;
262 for (
size_t j = 0; j < nv; ++j) {
264 ToPlane(panel.xv[j], panel.yv[j], panel.zv[j], u, v);
268 xpl.push_back(xpl[0]);
269 ypl.push_back(ypl[0]);
270 if (panel.colour < 0) {
271 pl.SetLineColor(kBlack);
273 pl.SetLineColor(panel.colour);
275 pl.DrawPolyLine(nv + 1, xpl.data(), ypl.data(),
"same");
284 std::cerr <<
m_className <<
"::PlotPanels: Geometry is not defined.\n";
288 const auto nSolids = m_geometry->GetNumberOfSolids();
290 std::cerr <<
m_className <<
"::PlotPanels: Geometry is empty.\n";
295 double xMin = 0., yMin = 0., zMin = 0.;
296 double xMax = 0., yMax = 0., zMax = 0.;
297 if (!m_geometry->GetBoundingBox(xMin, yMin, zMin, xMax, yMax, zMax)) {
298 std::cerr <<
m_className <<
"::PlotPanels: Cannot retrieve bounding box.\n";
304 for (
size_t i = 0; i < nSolids; ++i) {
305 auto solid = m_geometry->GetSolid(i);
306 if (!solid)
continue;
307 std::vector<Panel> panels;
308 if (!solid->SolidPanels(panels))
continue;
309 for (
const auto& panel : panels) {
310 const auto nv = panel.xv.size();
311 if (nv < 3)
continue;
312 std::vector<float> p;
313 for (
size_t k = 0; k < nv; ++k) {
314 p.push_back(panel.xv[k]);
315 p.push_back(panel.yv[k]);
316 p.push_back(panel.zv[k]);
318 p.push_back(panel.xv[0]);
319 p.push_back(panel.yv[0]);
320 p.push_back(panel.zv[0]);
321 TPolyLine3D pl(nv + 1, p.data());
323 if (panel.colour < 0) {
324 pl.SetLineColor(kBlack);
326 pl.SetLineColor(panel.colour);
328 pl.DrawPolyLine(nv + 1, p.data(),
"same");