Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:10:14

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2022 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/Plugins/ActSVG/SurfaceSvgConverter.hpp"
0010 
0011 #include "Acts/Surfaces/AnnulusBounds.hpp"
0012 #include "Acts/Surfaces/PlanarBounds.hpp"
0013 #include "Acts/Surfaces/Surface.hpp"
0014 
0015 Acts::Svg::ProtoSurface Acts::Svg::SurfaceConverter::convert(
0016     const GeometryContext& gctx, const Surface& surface,
0017     const SurfaceConverter::Options& cOptions) {
0018   ProtoSurface pSurface;
0019 
0020   // In case of non-template surfaces, the polyhedron does the trick
0021   if (!cOptions.templateSurface) {
0022     // Polyhedron surface for vertices needed anyway
0023     Polyhedron surfaceHedron =
0024         surface.polyhedronRepresentation(gctx, cOptions.style.nSegments);
0025     auto vertices3D = surfaceHedron.vertices;
0026     pSurface._vertices = vertices3D;
0027   } else {
0028     // In case it's a template surface, only the bounds matter
0029     // Check if planar bounds
0030     auto planarBounds =
0031         dynamic_cast<const Acts::PlanarBounds*>(&(surface.bounds()));
0032     if (planarBounds != nullptr) {
0033       auto vertices2D = planarBounds->vertices(cOptions.style.nSegments);
0034       pSurface._vertices.reserve(vertices2D.size());
0035       for (const auto& v2 : vertices2D) {
0036         pSurface._vertices.push_back({v2[0], v2[1], 0.});
0037       }
0038     } else {
0039       // Or annulus bounds
0040       auto annulusBounds =
0041           dynamic_cast<const Acts::AnnulusBounds*>(&(surface.bounds()));
0042       if (annulusBounds != nullptr) {
0043         auto vertices2D = annulusBounds->vertices(cOptions.style.nSegments);
0044         pSurface._vertices.reserve(vertices2D.size());
0045         for (const auto& v2 : vertices2D) {
0046           pSurface._vertices.push_back({v2[0], v2[1], 0.});
0047         }
0048       } else if (surface.type() == Acts::Surface::SurfaceType::Disc) {
0049         // Or disc bounds
0050         const auto& boundValues = surface.bounds().values();
0051         if (surface.bounds().type() == Acts::SurfaceBounds::BoundsType::eDisc) {
0052           // The radii
0053           actsvg::scalar ri = static_cast<actsvg::scalar>(boundValues[0]);
0054           actsvg::scalar ro = static_cast<actsvg::scalar>(boundValues[1]);
0055           pSurface._radii = {ri, ro};
0056           pSurface._opening = {
0057               static_cast<actsvg::scalar>(boundValues[3] - boundValues[2]),
0058               static_cast<actsvg::scalar>(boundValues[3] + boundValues[2])};
0059 
0060           actsvg::scalar pl = pSurface._opening[0];
0061           actsvg::scalar ph = pSurface._opening[1];
0062 
0063           pSurface._vertices = {
0064               {static_cast<actsvg::scalar>(ri * std::cos(pl)),
0065                static_cast<actsvg::scalar>(ri * std::sin(pl)), 0.},
0066               {static_cast<actsvg::scalar>(ro * std::cos(ph)),
0067                static_cast<actsvg::scalar>(ro * std::sin(ph)), 0.},
0068               {static_cast<actsvg::scalar>(ri * std::cos(pl)),
0069                static_cast<actsvg::scalar>(ri * std::sin(pl)), 0.},
0070               {static_cast<actsvg::scalar>(ro * std::cos(ph)),
0071                static_cast<actsvg::scalar>(ro * std::sin(ph)), 0.}};
0072         }
0073       }
0074     }
0075   }
0076 
0077   // Bound types and values
0078   const auto& boundValues = surface.bounds().values();
0079   auto bType = surface.bounds().type();
0080   auto bValues = surface.bounds().values();
0081   if (bType == Acts::SurfaceBounds::BoundsType::eRectangle) {
0082     pSurface._type = ProtoSurface::type::e_rectangle;
0083     // Set the measure
0084     pSurface._measures = {
0085         static_cast<actsvg::scalar>(0.5 * (boundValues[2] - boundValues[0])),
0086         static_cast<actsvg::scalar>(0.5 * (boundValues[3] - boundValues[1]))};
0087   } else if (bType == Acts::SurfaceBounds::BoundsType::eTrapezoid) {
0088     pSurface._type = ProtoSurface::type::e_trapez;
0089     // Set the measure
0090     pSurface._measures = {static_cast<actsvg::scalar>(boundValues[0]),
0091                           static_cast<actsvg::scalar>(boundValues[1]),
0092                           static_cast<actsvg::scalar>(boundValues[2])};
0093   } else if (bType == Acts::SurfaceBounds::BoundsType::eDiamond) {
0094     // Set the measure
0095     for (const auto& bv : boundValues) {
0096       pSurface._measures.push_back(static_cast<actsvg::scalar>(bv));
0097     }
0098   } else if (bType == Acts::SurfaceBounds::BoundsType::eAnnulus) {
0099     pSurface._type = ProtoSurface::type::e_trapez;
0100     // Set the measure
0101     for (const auto& bv : boundValues) {
0102       pSurface._measures.push_back(static_cast<actsvg::scalar>(bv));
0103     }
0104   } else if (bType == Acts::SurfaceBounds::BoundsType::eDisc) {
0105     pSurface._type = ProtoSurface::type::e_disc;
0106     // Set the openings
0107     actsvg::scalar ri = static_cast<actsvg::scalar>(boundValues[0]);
0108     actsvg::scalar ro = static_cast<actsvg::scalar>(boundValues[1]);
0109     actsvg::scalar zp = static_cast<actsvg::scalar>(surface.center(gctx).z());
0110     pSurface._radii = {ri, ro};
0111     pSurface._zparameters = {zp, zp};
0112     pSurface._opening = {
0113         static_cast<actsvg::scalar>(boundValues[3] - boundValues[2]),
0114         static_cast<actsvg::scalar>(boundValues[3] + boundValues[2])};
0115     // Set the measure
0116     for (const auto& bv : boundValues) {
0117       pSurface._measures.push_back(static_cast<actsvg::scalar>(bv));
0118     }
0119   }
0120 
0121   // Decorations
0122   // - Flag the material
0123   if (surface.surfaceMaterial() != nullptr) {
0124     pSurface._decorations["material"] = actsvg::svg::object{};
0125   }
0126 
0127   /// - The geometry ID as string
0128   actsvg::svg::object geoId{};
0129   geoId._id = std::to_string(surface.geometryId().value());
0130   pSurface._decorations["geo_id"] = geoId;
0131 
0132   // Attach the style
0133   pSurface._fill._fc = {
0134       cOptions.style.fillColor,
0135       static_cast<actsvg::scalar>(cOptions.style.fillOpacity)};
0136 
0137   // Fill style
0138   pSurface._fill._fc._hl_rgb = cOptions.style.highlightColor;
0139   pSurface._fill._fc._highlight = cOptions.style.highlights;
0140 
0141   // Stroke style
0142   pSurface._stroke._sc = actsvg::style::color{cOptions.style.strokeColor};
0143   pSurface._stroke._width = cOptions.style.strokeWidth;
0144 
0145   return pSurface;
0146 }