|
|
|||
File indexing completed on 2026-01-06 10:19:25
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/RevolvedPolygon.hh 0006 //---------------------------------------------------------------------------// 0007 #pragma once 0008 0009 #include "ObjectInterface.hh" 0010 #include "Solid.hh" 0011 0012 #include "detail/VolumeBuilder.hh" 0013 0014 namespace celeritas 0015 { 0016 namespace orangeinp 0017 { 0018 //---------------------------------------------------------------------------// 0019 /*! An azimuthally sliced arbitrary polygon revolved around the \em z axis. 0020 * 0021 * The polygon must be specified in counterclockwise order and may not be self 0022 * intersecting. The polygon cannot cross the \em z axis, i.e., all vertices 0023 * must satisfy \em r >= 0. 0024 * 0025 * Construction is performed using a convex differences tree approach 0026 * \citep{tor-convexdecomp-1984, https://doi.org/10.1145/357346.357348}. The 0027 * convex hull of the polygon is first found and revolved around the \em z 0028 * axis. Regions that constitute the difference between the convex hull and the 0029 * original polygon are then subtracted. Each of these regions is created 0030 * recursively in the same fashion. The recursion depth is referred to as the 0031 * "level" and each contiguous region within a level is a "region", as shown 0032 * below: 0033 * \verbatim 0034 original polygon convex hull difference 0035 |___ ____ |____________ | ______ 0036 ^ | \ | | | | | \ | level 1 0037 | | \ | | | | | \ | region 0 0038 z | \| | | level 0 | | \| 0039 | | = | region 0 | - | 0040 a | | | | | 0041 x | /\ | | | | /\ level 1 0042 i |___/ \____| |___________| | /__\ region 1 0043 s |_____________ |_____________ |_____________ 0044 r axis -> 0045 \endverbatim 0046 * Convex "regions" are constructed from "subregions", as shown below: 0047 * \verbatim 0048 | ______ |________ |___ 0049 ^ | \ | level 1 | | level 1 | \ level 1 0050 | | \ | region 0 | | region 0 | \ region 0 0051 z | \| |________| subregion 0 |_______\ subregion 1 0052 | = | (a cylinder) - | (a cone) 0053 a | | | 0054 x | | | 0055 i | | | 0056 s |_____________ |_____________ |_____________ 0057 r axis -> 0058 \endverbatim 0059 * In this example, level 1 region 0 is formed from only two subregions, but 0060 * the general case is handled via: 0061 * 0062 * region = union(outer subregions) - union(inner subregions). 0063 * 0064 * The final step in construction is azimuthal truncation, which is done 0065 * through a union operation with a negated or non-negated EnclosedAzi. 0066 * 0067 * \internal When labeling nodes in the CSG output, the following shorthand 0068 * format is used: `label@level.region.subregion`. For example, the final 0069 * subregion in the example above might be named `my_shape@1.0.1`. For each 0070 * level, additional nodes are created in the form: `label@level.suffix` where 0071 * suffixes have the following meanings: 0072 * 0073 * 1) .cu : the union of all concave regions on the level, 0074 * 2) .ncu : the negation of .cu, 0075 * 3) .d : the difference between the level's convex hull and .cu. 0076 * 0077 * For each region, additional nodes are created in the form 0078 * label@level.region.suffix where suffixes have the following meanings: 0079 * 0080 * 1) .ou : the union of nodes that comprise the outer boundary of the region, 0081 * 2) .iu : the union of nodes that comprise the inner boundary of the region, 0082 * 3) .nui : the negation of .ui, 0083 * 4) .d : the difference between .ou and .iu. 0084 * 0085 * If the supplied EnclosedAzi object is not [0, 2pi], additional nodes with 0086 * the following extensions are added: 0087 * 0088 * 1) azi/~azi : the enclosed, possibly negated, azimuthal angle, 0089 * 2) restricted : the intersection of the revolved polygon and azi/~azi. 0090 */ 0091 class RevolvedPolygon final : public ObjectInterface 0092 { 0093 public: 0094 //!@{ 0095 //! \name Type aliases 0096 using SPConstObject = std::shared_ptr<ObjectInterface const>; 0097 using VecReal2 = std::vector<Real2>; 0098 //!@} 0099 0100 // Construct from a polygon 0101 RevolvedPolygon(std::string&& label, 0102 VecReal2&& polygon, 0103 EnclosedAzi&& enclosed); 0104 0105 //// INTERFACE //// 0106 0107 //! Get the user-provided label 0108 std::string_view label() const final { return label_; } 0109 0110 //! Construct a volume from this object 0111 NodeId build(VolumeBuilder&) const final; 0112 0113 //! Write the shape to JSON 0114 void output(JsonPimpl*) const final; 0115 0116 //// ACCESSORS //// 0117 0118 //! Get the polygon 0119 VecReal2 const& polygon() const { return polygon_; }; 0120 0121 //! Get the azimuthal angular restriction 0122 EnclosedAzi const& enclosed_azi() const { return enclosed_; } 0123 0124 private: 0125 /// TYPES /// 0126 0127 // Helper struct for keeping track of levels/regions/subregions 0128 struct SubIndex 0129 { 0130 size_type level = 0; 0131 size_type region = 0; 0132 size_type subregion = 0; 0133 }; 0134 0135 //// HELPER METHODS //// 0136 0137 // Recursively construct convex regions, subtracting out concavities 0138 NodeId make_levels(detail::VolumeBuilder& vb, 0139 VecReal2 const& polygon, 0140 SubIndex si) const; 0141 0142 // Revolve a convex polygon around the \em z axis 0143 NodeId make_region(detail::VolumeBuilder& vb, 0144 VecReal2 const& polygon, 0145 SubIndex si) const; 0146 0147 // Make a translated cylinder node 0148 NodeId make_cylinder(detail::VolumeBuilder& vb, 0149 Real2 const& p0, 0150 Real2 const& p1, 0151 SubIndex const& si) const; 0152 0153 // Make a translated cone node 0154 NodeId make_cone(detail::VolumeBuilder& vb, 0155 Real2 const& p0, 0156 Real2 const& p1, 0157 SubIndex const& si) const; 0158 0159 // Make a label extension for a level 0160 std::string make_level_ext(SubIndex si) const; 0161 0162 // Make a label extension for a region within a level 0163 std::string make_region_ext(SubIndex si) const; 0164 0165 // Make a label extension for a subregion within a region 0166 std::string make_subregion_ext(SubIndex si) const; 0167 0168 //// DATA //// 0169 0170 std::string label_; 0171 VecReal2 polygon_; 0172 EnclosedAzi enclosed_; 0173 }; 0174 0175 //---------------------------------------------------------------------------// 0176 } // namespace orangeinp 0177 } // namespace celeritas
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|