Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SurfaceSvgConverter.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SurfaceSvgConverter.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2022 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
14 
16  const GeometryContext& gctx, const Surface& surface,
17  const SurfaceConverter::Options& cOptions) {
19 
20  // In case of non-template surfaces, the polyhedron does the trick
21  if (not cOptions.templateSurface) {
22  // Polyhedron surface for vertices needed anyway
23  Polyhedron surfaceHedron =
24  surface.polyhedronRepresentation(gctx, cOptions.style.nSegments);
25  auto vertices3D = surfaceHedron.vertices;
26  pSurface._vertices = vertices3D;
27  } else {
28  // In case it's a template surface, only the bounds matter
29  // Check if planar bounds
30  auto planarBounds =
31  dynamic_cast<const Acts::PlanarBounds*>(&(surface.bounds()));
32  if (planarBounds != nullptr) {
33  auto vertices2D = planarBounds->vertices(cOptions.style.nSegments);
34  pSurface._vertices.reserve(vertices2D.size());
35  for (const auto& v2 : vertices2D) {
36  pSurface._vertices.push_back({v2[0], v2[1], 0.});
37  }
38  } else {
39  // Or annulus bounds
40  auto annulusBounds =
41  dynamic_cast<const Acts::AnnulusBounds*>(&(surface.bounds()));
42  if (annulusBounds != nullptr) {
43  auto vertices2D = annulusBounds->vertices(cOptions.style.nSegments);
44  pSurface._vertices.reserve(vertices2D.size());
45  for (const auto& v2 : vertices2D) {
46  pSurface._vertices.push_back({v2[0], v2[1], 0.});
47  }
48  } else if (surface.type() == Acts::Surface::SurfaceType::Disc) {
49  // Or disc bounds
50  const auto& boundValues = surface.bounds().values();
51  if (surface.bounds().type() == Acts::SurfaceBounds::BoundsType::eDisc) {
52  // The radii
53  actsvg::scalar ri = static_cast<actsvg::scalar>(boundValues[0]);
54  actsvg::scalar ro = static_cast<actsvg::scalar>(boundValues[1]);
55  pSurface._radii = {ri, ro};
56  pSurface._opening = {
57  static_cast<actsvg::scalar>(boundValues[3] - boundValues[2]),
58  static_cast<actsvg::scalar>(boundValues[3] + boundValues[2])};
59 
60  actsvg::scalar pl = pSurface._opening[0];
61  actsvg::scalar ph = pSurface._opening[1];
62 
63  pSurface._vertices = {
64  {static_cast<actsvg::scalar>(ri * std::cos(pl)),
65  static_cast<actsvg::scalar>(ri * std::sin(pl)), 0.},
66  {static_cast<actsvg::scalar>(ro * std::cos(ph)),
67  static_cast<actsvg::scalar>(ro * std::sin(ph)), 0.},
68  {static_cast<actsvg::scalar>(ri * std::cos(pl)),
69  static_cast<actsvg::scalar>(ri * std::sin(pl)), 0.},
70  {static_cast<actsvg::scalar>(ro * std::cos(ph)),
71  static_cast<actsvg::scalar>(ro * std::sin(ph)), 0.}};
72  }
73  }
74  }
75  }
76 
77  // Bound types and values
78  const auto& boundValues = surface.bounds().values();
79  auto bType = surface.bounds().type();
80  auto bValues = surface.bounds().values();
81  if (bType == Acts::SurfaceBounds::BoundsType::eRectangle) {
82  pSurface._type = ProtoSurface::type::e_rectangle;
83  // Set the measure
84  pSurface._measures = {
85  static_cast<actsvg::scalar>(0.5 * (boundValues[2] - boundValues[0])),
86  static_cast<actsvg::scalar>(0.5 * (boundValues[3] - boundValues[1]))};
87  } else if (bType == Acts::SurfaceBounds::BoundsType::eTrapezoid) {
88  pSurface._type = ProtoSurface::type::e_trapez;
89  // Set the measure
90  pSurface._measures = {static_cast<actsvg::scalar>(boundValues[0]),
91  static_cast<actsvg::scalar>(boundValues[1]),
92  static_cast<actsvg::scalar>(boundValues[2])};
93  } else if (bType == Acts::SurfaceBounds::BoundsType::eDiamond) {
94  // Set the measure
95  for (const auto& bv : boundValues) {
96  pSurface._measures.push_back(static_cast<actsvg::scalar>(bv));
97  }
98  } else if (bType == Acts::SurfaceBounds::BoundsType::eAnnulus) {
99  pSurface._type = ProtoSurface::type::e_trapez;
100  // Set the measure
101  for (const auto& bv : boundValues) {
102  pSurface._measures.push_back(static_cast<actsvg::scalar>(bv));
103  }
104  } else if (bType == Acts::SurfaceBounds::BoundsType::eDisc) {
105  pSurface._type = ProtoSurface::type::e_disc;
106  // Set the openings
107  actsvg::scalar ri = static_cast<actsvg::scalar>(boundValues[0]);
108  actsvg::scalar ro = static_cast<actsvg::scalar>(boundValues[1]);
109  actsvg::scalar zp = static_cast<actsvg::scalar>(surface.center(gctx).z());
110  pSurface._radii = {ri, ro};
111  pSurface._zparameters = {zp, zp};
112  pSurface._opening = {
113  static_cast<actsvg::scalar>(boundValues[3] - boundValues[2]),
114  static_cast<actsvg::scalar>(boundValues[3] + boundValues[2])};
115  // Set the measure
116  for (const auto& bv : boundValues) {
117  pSurface._measures.push_back(static_cast<actsvg::scalar>(bv));
118  }
119  }
120 
121  // Attach the style
122  pSurface._fill._fc = {
123  cOptions.style.fillColor,
124  static_cast<actsvg::scalar>(cOptions.style.fillOpacity)};
125 
126  // Fill style
127  pSurface._fill._fc._hl_rgb = cOptions.style.highlightColor;
128  pSurface._fill._fc._highlight = cOptions.style.highlights;
129 
130  // Stroke style
131  pSurface._stroke._sc = actsvg::style::color{cOptions.style.strokeColor};
132  pSurface._stroke._width = cOptions.style.strokeWidth;
133 
134  return pSurface;
135 }