|
|
|||
File indexing completed on 2026-11-13 11:00:28
0001 // This file is part of VecGeom and is distributed under the 0002 // conditions in the file LICENSE.txt in the top directory. 0003 // For the full list of authors see CONTRIBUTORS.txt and `git log`. 0004 0005 /// \brief Host-side clipped extent helper for AABB and convex polyhedral envelopes. 0006 /// \file volumes/utilities/BoundingEnvelope.h 0007 0008 #ifndef VECGEOM_VOLUMES_UTILITIES_BOUNDINGENVELOPE_H_ 0009 #define VECGEOM_VOLUMES_UTILITIES_BOUNDINGENVELOPE_H_ 0010 0011 #include "VecGeom/volumes/utilities/ClippedExtent.h" 0012 0013 #include <vector> 0014 0015 namespace vecgeom { 0016 0017 namespace clipped_extent_detail { 0018 0019 /// @brief One convex envelope face described by local vertex indices. 0020 struct BoundingEnvelopeFace { 0021 /// Indices into the owning convex piece vertex array. 0022 std::vector<int> vertices; 0023 }; 0024 0025 /// @brief One convex local envelope piece consumed by `BoundingEnvelope`. 0026 struct BoundingEnvelopeConvexPiece { 0027 /// Local-frame vertices of the convex piece. 0028 std::vector<Vector3D<Precision>> local_vertices; 0029 /// Faces defining the convex piece boundary. 0030 std::vector<BoundingEnvelopeFace> faces; 0031 }; 0032 0033 } // namespace clipped_extent_detail 0034 0035 /// @brief Host-side clipped extent helper for conservative convex envelopes. 0036 /// 0037 /// @details 0038 /// A `BoundingEnvelope` stores one or more local-frame convex pieces. Queries 0039 /// transform those pieces to the mother frame, clip them against `VoxelLimits`, 0040 /// and return conservative axis-aligned bounds. Multiple pieces are combined as 0041 /// a union, so non-convex solids can be represented by conservative convex 0042 /// decompositions. 0043 class BoundingEnvelope { 0044 public: 0045 BoundingEnvelope() = default; 0046 0047 /// @brief Construct an envelope from one local AABB. 0048 /// @param local_min Local lower AABB corner. 0049 /// @param local_max Local upper AABB corner. 0050 BoundingEnvelope(Vector3D<Precision> const &local_min, Vector3D<Precision> const &local_max); 0051 0052 /// @brief Construct an envelope from one local AABB. 0053 /// @param local_min Local lower AABB corner. 0054 /// @param local_max Local upper AABB corner. 0055 /// @return Bounding envelope containing one AABB piece. 0056 static BoundingEnvelope FromLocalAABB(Vector3D<Precision> const &local_min, Vector3D<Precision> const &local_max) 0057 { 0058 return BoundingEnvelope(local_min, local_max); 0059 } 0060 0061 /// @brief Add one prism with matching lower and upper polygon bases. 0062 /// @param lower_base Local vertices of the lower base polygon. 0063 /// @param lower_count Number of vertices in `lower_base`. 0064 /// @param upper_base Local vertices of the upper base polygon. 0065 /// @param upper_count Number of vertices in `upper_base`; must match `lower_count`. 0066 void AddLocalPrism(const Vector3D<Precision> *lower_base, int lower_count, const Vector3D<Precision> *upper_base, 0067 int upper_count); 0068 0069 #ifndef VECCORE_CUDA 0070 /// @brief Add a conservative angular decomposition of one local conical frustum. 0071 /// 0072 /// @details 0073 /// The frustum is split into convex phi cells. Outer circular arcs are 0074 /// circumscribed by scaling the outer radii on each cell boundary by 0075 /// `1 / cos(cell_delta_phi / 2)`, matching the envelope idea used by 0076 /// Geant4 polycone extents. Inner radii stay unscaled, which may over-cover 0077 /// the hole but does not under-cover the solid. `full_phi_segments` controls 0078 /// the number of cells used for a full `2*pi` revolution. 0079 /// 0080 /// @param rmin1 Inner radius at `z1`. 0081 /// @param rmax1 Outer radius at `z1`. 0082 /// @param rmin2 Inner radius at `z2`. 0083 /// @param rmax2 Outer radius at `z2`. 0084 /// @param z1 Lower or first z plane of the frustum. 0085 /// @param z2 Upper or second z plane of the frustum. 0086 /// @param phi_start Start angle in local coordinates. 0087 /// @param phi_delta Phi opening angle in radians. 0088 /// @param full_phi_segments Number of angular cells used for a full circle. 0089 void AddLocalConicalFrustum(Precision rmin1, Precision rmax1, Precision rmin2, Precision rmax2, Precision z1, 0090 Precision z2, Precision phi_start, Precision phi_delta, int full_phi_segments = 24); 0091 0092 /// @brief Add a conservative circumscribed envelope for a full local sphere. 0093 /// 0094 /// @details 0095 /// The sphere is decomposed into theta bands with regular phi polygons. 0096 /// Ring vertices are placed at angular cell centers and scaled by 0097 /// `1 / cos(half_cell_angle)`, so the meridian and phi polygons both 0098 /// circumscribe the spherical surface. The default 8 theta and 16 phi 0099 /// segments match the `G4Orb` clipped-extent envelope. 0100 /// 0101 /// @param radius Sphere radius. 0102 /// @param theta_segments Number of bands in polar angle. 0103 /// @param phi_segments Number of angular cells in a full circle. 0104 void AddLocalSphere(Precision radius, int theta_segments = 8, int phi_segments = 16); 0105 0106 /// @brief Add a conservative full-phi elliptical frustum envelope. 0107 /// 0108 /// @details 0109 /// Each z end is covered by an affine-scaled tangent polygon of the local 0110 /// ellipse, using the same `1 / cos(cell_delta_phi / 2)` circumscription as 0111 /// circular frustum envelopes. The helper covers solid elliptical frusta with 0112 /// no inner hole; equal lower and upper radii produce an elliptical cylinder. 0113 /// 0114 /// @param x_radius1 Semi-axis in x at `z1`. 0115 /// @param y_radius1 Semi-axis in y at `z1`. 0116 /// @param x_radius2 Semi-axis in x at `z2`. 0117 /// @param y_radius2 Semi-axis in y at `z2`. 0118 /// @param z1 Lower or first z plane of the frustum. 0119 /// @param z2 Upper or second z plane of the frustum. 0120 /// @param full_phi_segments Number of angular cells used for a full ellipse. 0121 void AddLocalEllipticalFrustum(Precision x_radius1, Precision y_radius1, Precision x_radius2, Precision y_radius2, 0122 Precision z1, Precision z2, int full_phi_segments = 24); 0123 #endif 0124 0125 /// @brief Add one finite convex polyhedral envelope piece from local vertices and faces. 0126 /// 0127 /// @details 0128 /// Faces are described by contiguous entries in `face_indices`; each 0129 /// `face_vertex_counts[i]` gives the number of vertex indices for face `i`. 0130 /// Face orientation is not significant: plane normals are oriented from the 0131 /// piece centroid when the envelope is clipped. This helper is intended for 0132 /// exact or conservative convex pieces such as tetrahedra, pyramids, and 0133 /// future convex decompositions; non-convex solids must add multiple convex 0134 /// pieces or use another conservative envelope. 0135 /// 0136 /// @param vertices Local-frame vertices. 0137 /// @param vertex_count Number of vertices. 0138 /// @param face_indices Contiguous face vertex indices. 0139 /// @param face_index_count Number of entries in `face_indices`. 0140 /// @param face_vertex_counts Number of vertices for each face. 0141 /// @param face_count Number of faces. 0142 void AddLocalConvexPolyhedron(const Vector3D<Precision> *vertices, int vertex_count, const int *face_indices, 0143 int face_index_count, const int *face_vertex_counts, int face_count); 0144 0145 /// @brief Calculate one clipped mother-frame extent interval. 0146 /// @param axis Axis to project. 0147 /// @param limits Mother-frame clipping limits. 0148 /// @param transform Local-to-mother transform. 0149 /// @param[out] min Lower extent along `axis` when an overlap exists. 0150 /// @param[out] max Upper extent along `axis` when an overlap exists. 0151 /// @param tolerance Final symmetric inflation applied before limiting. 0152 /// @return True when the envelope intersects `limits`. 0153 bool CalculateExtent(Axis axis, VoxelLimits const &limits, Transformation3D const &transform, Precision &min, 0154 Precision &max, Precision tolerance = kAABBPadding) const; 0155 0156 /// @brief Calculate a clipped mother-frame AABB for all stored pieces. 0157 /// @param limits Mother-frame clipping limits. 0158 /// @param transform Local-to-mother transform. 0159 /// @param tolerance Final symmetric inflation applied before limiting. 0160 /// @return Conservative clipped box; `exists` is false when no piece overlaps. 0161 ClippedBox CalculateClippedBox(VoxelLimits const &limits, Transformation3D const &transform, 0162 Precision tolerance = kAABBPadding) const; 0163 0164 private: 0165 std::vector<clipped_extent_detail::BoundingEnvelopeConvexPiece> fPieces; 0166 }; 0167 0168 } // namespace vecgeom 0169 0170 #endif // VECGEOM_VOLUMES_UTILITIES_BOUNDINGENVELOPE_H_
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|