|
|
|||
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/StackedExtrudedPolygon.hh 0006 //---------------------------------------------------------------------------// 0007 #pragma once 0008 0009 #include "ObjectInterface.hh" 0010 0011 #include "detail/VolumeBuilder.hh" 0012 0013 namespace celeritas 0014 { 0015 namespace orangeinp 0016 { 0017 //---------------------------------------------------------------------------// 0018 /*! A convex/concave polygon extruded along a polyline, with scaling. 0019 * 0020 * The polygon must be specified in counterclockwise order. The polyline must 0021 * be strictly monotonically increasing in z. Scaling factors can be any 0022 * positive value. Scaling is assumed to occur with respect to the polygon's 0023 * original coordinate system. 0024 * 0025 * Construction is performed using a convex decomposition approach 0026 * \citep{tor-convexdecomp-1984, https://doi.org/10.1145/357346.357348}. The 0027 * convex hull of the polygon is first found, then extruded along the polyline 0028 * (with scaling) form a stack of ExtrudedPolygon shapes. Regions that 0029 * constitute the difference between the polygon and its convex hull are then 0030 * subtracted. Each of these regions is created recursively in the same 0031 * fashion, i.e. finding the convex hull and creating a stack. 0032 * 0033 * Because this method creates many regions, these are kept track of using 0034 * three indices for debugging purposes: level, stack, and segment. The level 0035 * index denotes the current recursion depth. The stack index denotes the 0036 * convex region which is extruded into a stack on a given level. The segment 0037 * index denotes the z segment within the stack. An example of these indices is 0038 * shown below. Consider the following polygon, extruded along a single-segment 0039 * polyline: 0040 * \verbatim 0041 __________ 0042 | | 0043 ___| | 0044 | | 0045 | | 0046 | | 0047 | __| 0048 | | 0049 |___________| 0050 \endverbatim 0051 * The convex hull of this polygon is used to create the first region: 0052 * \verbatim 0053 __________ 0054 / | 0055 / | 0056 | level 0 | 0057 | stack 0 | 0058 | segment 0 | 0059 | | 0060 | / 0061 |___________/ 0062 \endverbatim 0063 * Recursing one level deeper, we create two additional regions: 0064 * \verbatim 0065 0066 ........... 0067 /| level 1, stack 0, segment 0 0068 /__| . 0069 . . 0070 . . 0071 . . 0072 . ___. 0073 . | / level 1, stack 1, segment 0 0074 ...........|/ 0075 \endverbatim 0076 * and subtract their union from the first region. 0077 * 0078 * \internal When labeing nodes in the CSG output, the following shorthand 0079 * format is used: `label@level.stack.segment`. For example, the final region 0080 * in the example above might be named `my_shape@1.1.0`. For each level, 0081 * additional nodes are created in the form: `label@level.suffix` where 0082 * suffixes have the following meanings: 0083 * 1) .cu : the union of all concave regions on this level, 0084 * 2) .ncu : the negation of the union of all concave regions on this level, 0085 * 3) .d : the difference between this level's convex hull and the concave 0086 * regions on this level. 0087 */ 0088 class StackedExtrudedPolygon final : public ObjectInterface 0089 { 0090 public: 0091 //!@{ 0092 //! \name Type aliases 0093 using SPConstObject = std::shared_ptr<ObjectInterface const>; 0094 using VecReal = std::vector<real_type>; 0095 using VecReal2 = std::vector<Real2>; 0096 using VecReal3 = std::vector<Real3>; 0097 //!@} 0098 0099 //! Construct, or return an ExtrudedPolygon shape if possible 0100 static SPConstObject or_solid(std::string&& label, 0101 VecReal2&& polygon, 0102 VecReal3&& polyline, 0103 VecReal&& scaling); 0104 0105 // Construct from a polygon, polyline, and scaling factors 0106 StackedExtrudedPolygon(std::string&& label, 0107 VecReal2&& polygon, 0108 VecReal3&& polyline, 0109 VecReal&& scaling); 0110 0111 //// INTERFACE //// 0112 0113 //! Get the user-provided label 0114 std::string_view label() const final { return label_; } 0115 0116 //! Construct a volume from this object 0117 NodeId build(VolumeBuilder&) const final; 0118 0119 //! Write the shape to JSON 0120 void output(JsonPimpl*) const final; 0121 0122 //// ACCESSORS //// 0123 0124 //! Get the polygon 0125 VecReal2 const& polygon() const { return polygon_; }; 0126 0127 //! Get the polyline 0128 VecReal3 const& polyline() const { return polyline_; }; 0129 0130 //! Get the scaling factors 0131 VecReal const& scaling() const { return scaling_; }; 0132 0133 private: 0134 /// TYPES /// 0135 0136 // Helper struct for keeping track of embedded regions 0137 struct SubRegionIndex 0138 { 0139 size_type level = 0; 0140 size_type stack = 0; 0141 }; 0142 0143 //// HELPER METHODS //// 0144 0145 // Recursively construct stacks, subtracting out concavities 0146 NodeId make_levels(detail::VolumeBuilder& vb, 0147 VecReal2 const& polygon, 0148 SubRegionIndex si) const; 0149 0150 // Extrude a *convex* polygon along the polyline 0151 NodeId make_stack(detail::VolumeBuilder& vb, 0152 VecReal2 const& polygon, 0153 SubRegionIndex si) const; 0154 0155 // Make a label for a level 0156 std::string make_level_ext(SubRegionIndex si) const; 0157 0158 // Make a label for a stack within a level 0159 std::string make_stack_ext(SubRegionIndex si) const; 0160 0161 // Make a label for a segment within a stack 0162 std::string 0163 make_segment_ext(SubRegionIndex si, size_type segment_idx) const; 0164 0165 //// DATA //// 0166 0167 std::string label_; 0168 VecReal2 polygon_; 0169 VecReal3 polyline_; 0170 VecReal scaling_; 0171 }; 0172 0173 //---------------------------------------------------------------------------// 0174 } // namespace orangeinp 0175 } // 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 |
|