Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:24:49

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file orange/orangeinp/detail/NegatedSurfaceClipper.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "geocel/BoundingBox.hh"
0010 #include "orange/surf/PlaneAligned.hh"
0011 
0012 #include "BoundingZone.hh"
0013 
0014 namespace celeritas
0015 {
0016 namespace orangeinp
0017 {
0018 namespace detail
0019 {
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Truncate a bounding zone from a negated plane.
0023  *
0024  * A negated plane is one when "inside" the CSG node has an outward-facing
0025  * normal.
0026  *
0027  * \verbatim
0028             |--> PlaneAligned<T> outward normal
0029   exterior  |
0030        <----+---->  axis
0031             |
0032             |  interior
0033  * \endverbatim
0034  */
0035 class NegatedSurfaceClipper
0036 {
0037   public:
0038     // Construct with the bounding zone to clip
0039     explicit inline NegatedSurfaceClipper(BoundingZone* bz);
0040     // Construct with interior/exterior
0041     inline NegatedSurfaceClipper(BBox* interior, BBox* exterior);
0042 
0043     //! Clip axis-aligned planes.
0044     template<Axis T>
0045     CELER_FORCEINLINE void operator()(PlaneAligned<T> const& s)
0046     {
0047         return this->clip_impl(T, s.position());
0048     }
0049 
0050     //! All other operations invalidate the "interior" box
0051     template<class S>
0052     CELER_FORCEINLINE void operator()(S const&)
0053     {
0054         return this->invalidate();
0055     }
0056 
0057   private:
0058     BBox* interior_{nullptr};
0059     BBox* exterior_{nullptr};
0060 
0061     // Clip based on the given orthogonal plane
0062     inline void clip_impl(Axis ax, real_type pos);
0063 
0064     // Invalidate the interior zone due to non-convex surface
0065     inline void invalidate();
0066 };
0067 
0068 //---------------------------------------------------------------------------//
0069 /*!
0070  * Construct with the bounding zone to clip.
0071  */
0072 NegatedSurfaceClipper::NegatedSurfaceClipper(BoundingZone* bz)
0073     : interior_{&bz->interior}, exterior_{&bz->exterior}
0074 {
0075     CELER_EXPECT(bz && interior_ && exterior_);
0076 }
0077 
0078 //---------------------------------------------------------------------------//
0079 /*!
0080  * Construct with explicit but optional bounding boxes
0081  */
0082 NegatedSurfaceClipper::NegatedSurfaceClipper(BBox* interior, BBox* exterior)
0083     : interior_{interior}, exterior_{exterior}
0084 {
0085     CELER_EXPECT(interior_ || exterior_);
0086 }
0087 
0088 //---------------------------------------------------------------------------//
0089 /*!
0090  * Clip based on the given orthogonal plane.
0091  */
0092 void NegatedSurfaceClipper::clip_impl(Axis ax, real_type pos)
0093 {
0094     if (interior_)
0095     {
0096         interior_->shrink(Bound::lo, ax, pos);
0097     }
0098     if (exterior_)
0099     {
0100         exterior_->shrink(Bound::lo, ax, pos);
0101     }
0102 }
0103 
0104 //---------------------------------------------------------------------------//
0105 /*!
0106  * Invalidate the interior zone due to non-convex surface.
0107  */
0108 void NegatedSurfaceClipper::invalidate()
0109 {
0110     if (interior_)
0111     {
0112         *interior_ = {};
0113     }
0114 }
0115 
0116 //---------------------------------------------------------------------------//
0117 }  // namespace detail
0118 }  // namespace orangeinp
0119 }  // namespace celeritas