Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://www.mooseframework.org 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "CSGSurface.h" 13 : #include "MooseEnum.h" 14 : 15 : namespace CSG 16 : { 17 : 18 : /** 19 : * CSGRegions creates an internal representation of a CSG region, which can refer to 20 : * an intersection, union, complement, or half-space 21 : */ 22 : class CSGRegion 23 : { 24 : public: 25 : /// Enum for representing region types, defined to match _region_type MooseEnum 26 : enum class RegionType 27 : { 28 : EMPTY, 29 : HALFSPACE, 30 : COMPLEMENT, 31 : INTERSECTION, 32 : UNION 33 : }; 34 : 35 : /** 36 : * Type definition for a variant that represents the datatypes for entries within the list that 37 : * represents the region in postfix notation. This can be a surface reference, a region 38 : * type, or halfspace 39 : */ 40 : typedef std::variant<std::reference_wrapper<const CSGSurface>, RegionType, CSGSurface::Halfspace> 41 : PostfixTokenVariant; 42 : 43 : /** 44 : * @return The symbol associated with the given region type 45 : */ 46 : static char regionSymbol(const RegionType region_type); 47 : /** 48 : * @return The symbol associated with the given halfspace 49 : */ 50 : static char halfspaceSymbol(const CSGSurface::Halfspace halfspace); 51 : 52 : /** 53 : * Default Constructor 54 : */ 55 : CSGRegion(); 56 : 57 : /** 58 : * @brief Constructor for half-space of a surface 59 : * 60 : * @param surf referance to surface used to define the half-space 61 : * @param halfspace half-space to apply to surface (POSITIVE or NEGATIVE) 62 : */ 63 : CSGRegion(const CSGSurface & surf, const CSGSurface::Halfspace halfspace); 64 : 65 : /** 66 : * @brief Constructor for union and intersection 67 : * 68 : * @param region_a reference to first region to union or intersect 69 : * @param region_b reference to second region to union or intersect 70 : * @param region_type type of region operation (UNION or INTERSECTION) 71 : */ 72 : CSGRegion(const CSGRegion & region_a, 73 : const CSGRegion & region_b, 74 : const std::string & region_type); 75 : 76 : /** 77 : * @brief Constructor for complement or empty region (clear the region) 78 : * 79 : * @param region reference to region to apply complement 80 : * @param region_type type of region to apply (COMPLEMENT or EMPTY) 81 : */ 82 : CSGRegion(const CSGRegion & region, const std::string & region_type); 83 : 84 : /** 85 : * Destructor 86 : */ 87 1824 : virtual ~CSGRegion() = default; 88 : 89 : /** 90 : * @brief gets the infix JSON representation of the region, which involves converting 91 : * region representation from postfix to infix notation 92 : * 93 : * @return infix JSON representation of the region 94 : */ 95 : nlohmann::json toInfixJSON() const; 96 : 97 : /** 98 : * @brief gets the list of postfix tokens of the region in string representation 99 : * 100 : * @return list of postfix tokens that represent the region 101 : */ 102 : std::vector<std::string> toPostfixStringList() const; 103 : 104 : /** 105 : * @brief converts postfix token from PostfixTokenVariant to string representation 106 : * 107 : * @param token postfix token of type PostfixTokenVariant 108 : * @return string representation of postfix token 109 : */ 110 : std::string postfixTokenToString(const PostfixTokenVariant & token) const; 111 : 112 : /** 113 : * @brief Get the region type 114 : * 115 : * @return region type enum 116 : */ 117 2484 : RegionType getRegionType() const { return _region_type.getEnum<RegionType>(); } 118 : 119 : /** 120 : * @brief Get the region type as a string 121 : * 122 : * @return region type string 123 : */ 124 16 : const std::string getRegionTypeString() const { return _region_type; } 125 : 126 : /** 127 : * @brief Get the list of surfaces associated with the region 128 : * 129 : * @return list of references to surfaces that define the region 130 : */ 131 : std::vector<std::reference_wrapper<const CSGSurface>> getSurfaces() const; 132 : 133 : /** 134 : * @brief Update surface references of region based on map of input surface references 135 : * 136 : * @param identical_surface_refs map of surface name to surface references that region should be 137 : * defined with 138 : */ 139 : void updateSurfaceReferences( 140 : std::map<std::string, std::reference_wrapper<const CSGSurface>> & identical_surface_refs); 141 : 142 : /// Operator overload for &= which creates an intersection between the current region and the other_region 143 : CSGRegion & operator&=(const CSGRegion & other_region); 144 : 145 : /// Operator overload for |= which creates a union of the current region with the other_region 146 : CSGRegion & operator|=(const CSGRegion & other_region); 147 : 148 : /// Operator overload for checking if two CSGRegion objects are equal 149 : bool operator==(const CSGRegion & other) const; 150 : 151 : /// Operator overload for checking if two CSGRegion objects are not equal 152 : bool operator!=(const CSGRegion & other) const; 153 : 154 : protected: 155 : /** 156 : * @brief Get the list of postfix tokens associated with the region 157 : * 158 : * @return list of tokens that define the region in postfix notation 159 : */ 160 1970 : const std::vector<PostfixTokenVariant> & getPostfixTokens() const { return _postfix_tokens; } 161 : 162 : /** 163 : * @brief Iterate through postfix tokens and check if next region operator matches the given 164 : * operator 165 : * 166 : * @param region the region type 167 : * @param postfix_token_index index in _postfix_tokens to start region operator comparisons 168 : * @return true if next region operator in _postfix_tokens matches region_op_string, false 169 : * otherwise 170 : */ 171 : bool nextRegionOpIsIdentical(const RegionType region, 172 : const std::size_t postfix_token_index) const; 173 : 174 : /** 175 : * @brief Loop through postfix tokens and check equality with another list of postfix tokens 176 : * 177 : * @param other_tokens list of postfix tokens to compare to 178 : * @return true if postfix token lists are equal, false otherwise 179 : */ 180 : bool checkRegionEquality(const std::vector<PostfixTokenVariant> & other_tokens) const; 181 : 182 : /// An enum for type of type of operation that defines region 183 : MooseEnum _region_type{"EMPTY=0 HALFSPACE=1 COMPLEMENT=2 INTERSECTION=3 UNION=4"}; 184 : 185 : /// List of tokens representing the region in postfix notation 186 : std::vector<PostfixTokenVariant> _postfix_tokens; 187 : }; 188 : 189 : /// Operation overloads for operation based region construction 190 : 191 : /// Overload for creating a region from the positive half-space (+) of a surface 192 : const CSGRegion operator+(const CSGSurface & surf); 193 : 194 : /// Overload for creating a region from the negative half-space (-) of a surface 195 : const CSGRegion operator-(const CSGSurface & surf); 196 : 197 : /// Overload for creating a region from the the intersection (&) of two regions 198 : const CSGRegion operator&(const CSGRegion & region_a, const CSGRegion & region_b); 199 : 200 : /// Overload for creating a region from the union (|) of two regions 201 : const CSGRegion operator|(const CSGRegion & region_a, const CSGRegion & region_b); 202 : 203 : /// Overload for creating a region from the complement (~) of another region 204 : const CSGRegion operator~(const CSGRegion & region); 205 : 206 : } // namespace CSG