20 "Unexpected region type");
22 static constexpr std::array<char, 5> symbols = {
33 return symbols[
static_cast<std::size_t
>(region_type)];
41 "Unexpected halfspace");
43 static constexpr std::array<char, 2> symbols = {
50 return symbols[
static_cast<std::size_t
>(halfspace)];
57 if (tokens.size() != other_tokens.size())
61 for (
const auto i : index_range(tokens))
63 const auto &
token = tokens[i];
64 const auto & other_token = other_tokens[i];
65 if (std::holds_alternative<std::reference_wrapper<const CSGSurface>>(
token))
68 if (!std::holds_alternative<std::reference_wrapper<const CSGSurface>>(other_token))
70 const auto & surf_ref = std::get<std::reference_wrapper<const CSGSurface>>(
token);
71 const auto & other_surf_ref = std::get<std::reference_wrapper<const CSGSurface>>(other_token);
72 if (surf_ref.get() != other_surf_ref.get())
78 mooseAssert(std::holds_alternative<RegionType>(
token) ||
79 std::holds_alternative<CSGSurface::Halfspace>(
token),
80 "Unexpected token type");
81 if (std::holds_alternative<std::reference_wrapper<const CSGSurface>>(other_token))
95 "Unexpected region type");
97 static constexpr std::array<const char *, 5> names = {
105 std::string_view(
"COMPLEMENT"));
107 std::string_view(
"INTERSECTION"));
108 static_assert(names[
static_cast<std::size_t
>(
RegionType::UNION)] == std::string_view(
"UNION"));
110 return names[
static_cast<std::size_t
>(region_type)];
132 const std::string & region_type)
140 " cannot be performed on an empty region.");
174 return nlohmann::json::parse(
"[]");
177 std::stack<std::string> postfix_stack;
182 if (
const auto surface_ref_ptr = std::get_if<std::reference_wrapper<const CSGSurface>>(&
token))
183 postfix_stack.push(surface_ref_ptr->get().getName());
187 std::string region_string;
189 if (
const auto halfspace_ptr = std::get_if<CSGSurface::Halfspace>(&
token))
192 region_string =
"\"" + symbol + postfix_stack.top() +
"\"";
198 const auto region = std::get<RegionType>(
token);
202 region_string = postfix_stack.top();
204 if (region_string[0] ==
'[')
205 region_string =
"\"" + symbol +
"\", " + region_string;
207 region_string =
"\"" + symbol +
"\", [" + region_string +
"]";
211 auto region_string_b = postfix_stack.top();
213 auto region_string_a = postfix_stack.top();
215 region_string = region_string_a +
", \"" + symbol +
"\", " + region_string_b;
219 region_string =
"[" + region_string +
"]";
222 postfix_stack.push(region_string);
228 std::string region_string = postfix_stack.top();
231 if (region_string[0] !=
'[')
232 region_string =
"[" + region_string +
"]";
233 return nlohmann::json::parse(region_string);
236std::vector<std::string>
239 std::vector<std::string> postfix_string_list;
243 return postfix_string_list;
251 [](
auto && arg) -> std::string
253 using T = std::decay_t<
decltype(arg)>;
254 if constexpr (std::is_same_v<T, std::reference_wrapper<const CSGSurface>>)
255 return arg.get().getName();
256 else if constexpr (std::is_same_v<T, RegionType>)
266 const std::size_t postfix_token_index)
const
268 for (
const auto i : make_range(postfix_token_index,
_postfix_tokens.size()))
269 if (
const auto region_ptr = std::get_if<RegionType>(&
_postfix_tokens[i]))
270 return region == *region_ptr;
276 std::map<std::string, std::reference_wrapper<const CSGSurface>> & identical_surface_refs)
279 if (std::holds_alternative<std::reference_wrapper<const CSGSurface>>(
token))
281 const auto & surf_ref = std::get<std::reference_wrapper<const CSGSurface>>(
token);
282 const auto & surf_name = surf_ref.get().getName();
283 if (identical_surface_refs.find(surf_name) != identical_surface_refs.end())
284 token = identical_surface_refs.at(surf_name);
288std::vector<std::reference_wrapper<const CSGSurface>>
291 std::vector<std::reference_wrapper<const CSGSurface>> surface_references;
293 if (std::holds_alternative<std::reference_wrapper<const CSGSurface>>(
token))
294 surface_references.push_back(std::get<std::reference_wrapper<const CSGSurface>>(
token));
296 return surface_references;
302 if (
this != &other_region)
303 *
this =
CSGRegion(*
this, other_region,
"INTERSECTION");
310 if (
this != &other_region)
311 *
this =
CSGRegion(*
this, other_region,
"UNION");
335 return CSGRegion(region_a, region_b,
"INTERSECTION");
342 return CSGRegion(region_a, region_b,
"UNION");
362 return !(*
this == other);
372 std::vector<PostfixTokenVariant> new_tokens;
376 const auto * ref_ptr =
377 std::get_if<std::reference_wrapper<const CSGSurface>>(&
_postfix_tokens[i]);
379 if (ref_ptr && &ref_ptr->get() == &old_surf)
386 "Expected a Halfspace token after surface reference in postfix stream");
387 const auto & hs = std::get<CSGSurface::Halfspace>(
_postfix_tokens[++i]);
405 else if (
const auto * rt = std::get_if<RegionType>(&
_postfix_tokens.back()))
409 mooseAssert(std::holds_alternative<CSGSurface::Halfspace>(
_postfix_tokens.back()),
410 "Expected halfspace as last token");
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
CSGRegions creates an internal representation of a CSG region, which can refer to an intersection,...
void updateSurfaceReferences(std::map< std::string, std::reference_wrapper< const CSGSurface > > &identical_surface_refs)
Update surface references of region based on map of input surface references.
RegionType getRegionType() const
Get the region type.
void replaceWithSubRegion(const CSGSurface &old_surf, const CSGRegion &sub_region)
Replace all occurrences of old_surf in this region's postfix token stream with the tokens of sub_regi...
bool nextRegionOpIsIdentical(const RegionType region, const std::size_t postfix_token_index) const
Iterate through postfix tokens and check if next region operator matches the given operator.
static char regionSymbol(const RegionType region_type)
std::vector< PostfixTokenVariant > _postfix_tokens
List of tokens representing the region in postfix notation.
MooseEnum _region_type
An enum for type of type of operation that defines region.
bool operator==(const CSGRegion &other) const
Operator overload for checking if two CSGRegion objects are equal.
bool operator!=(const CSGRegion &other) const
Operator overload for checking if two CSGRegion objects are not equal.
bool checkRegionEquality(const std::vector< PostfixTokenVariant > &other_tokens) const
Loop through postfix tokens and check equality with another list of postfix tokens.
RegionType
Enum for representing region types, defined to match _region_type MooseEnum.
CSGRegion & operator&=(const CSGRegion &other_region)
Operator overload for &= which creates an intersection between the current region and the other_regio...
std::vector< std::reference_wrapper< const CSGSurface > > getSurfaces() const
Get the list of surfaces associated with the region.
static char halfspaceSymbol(const CSGSurface::Halfspace halfspace)
static std::string regionTypeName(const RegionType region_type)
std::vector< std::string > toPostfixStringList() const
gets the list of postfix tokens of the region in string representation
std::variant< std::reference_wrapper< const CSGSurface >, RegionType, CSGSurface::Halfspace > PostfixTokenVariant
Type definition for a variant that represents the datatypes for entries within the list that represen...
nlohmann::json toInfixJSON() const
gets the infix JSON representation of the region, which involves converting region representation fro...
const std::string getRegionTypeString() const
Get the region type as a string.
CSGRegion()
Default Constructor.
const std::vector< PostfixTokenVariant > & getPostfixTokens() const
Get the list of postfix tokens associated with the region.
std::string postfixTokenToString(const PostfixTokenVariant &token) const
converts postfix token from PostfixTokenVariant to string representation
CSGRegion & operator|=(const CSGRegion &other_region)
Operator overload for |= which creates a union of the current region with the other_region.
CSGSurface creates an internal representation of a Constructive Solid Geometry (CSG) surface,...
Halfspace
Enum for the sign of the half-space being represented by a point and surface.
const CSGRegion operator|(const CSGRegion ®ion_a, const CSGRegion ®ion_b)
Overload for creating a region from the union (|) of two regions.
const CSGRegion operator~(const CSGRegion ®ion)
Overload for creating a region from the complement (~) of another region.
const CSGRegion operator&(const CSGRegion ®ion_a, const CSGRegion ®ion_b)
Overload for creating a region from the the intersection (&) of two regions.
const CSGRegion operator-(const CSGSurface &surf)
Overload for creating a region from the negative half-space (-) of a surface.
const CSGRegion operator+(const CSGSurface &surf)
Operation overloads for operation based region construction.