|
||||
File indexing completed on 2025-01-30 10:17:11
0001 //----------------------------------*-C++-*----------------------------------// 0002 // Copyright 2023-2024 UT-Battelle, LLC, and other Celeritas developers. 0003 // See the top-level COPYRIGHT file for details. 0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0005 //---------------------------------------------------------------------------// 0006 //! \file orange/orangeinp/CsgTree.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <iostream> 0011 #include <optional> 0012 #include <unordered_map> 0013 #include <variant> 0014 #include <vector> 0015 0016 #include "corecel/OpaqueId.hh" 0017 #include "corecel/math/HashUtils.hh" 0018 0019 #include "CsgTypes.hh" 0020 0021 namespace celeritas 0022 { 0023 namespace orangeinp 0024 { 0025 //---------------------------------------------------------------------------// 0026 /*! 0027 * DAG of constructed CSG nodes within a universe. 0028 * 0029 * Inserting a new node performs one local simplification for "join" types 0030 * (removing duplicates, replacing zero- and one- entry special cases); and all 0031 * nodes are inserted into a deduplicated map of nodes that may be further 0032 * simplified later (see \c CsgAlgorithms). 0033 * 0034 * The tree is a topologically sorted graph where the leaves are the lower node 0035 * indices. The intent is for higher nodes to be simplified to boolean values, 0036 * e.g., by representing that all points in space are inside a cylinder by 0037 * replacing a \c Joined node with \c True . To facilitate this while 0038 * preserving node indices, \c True and \c False nodes are automatically 0039 * inserted as the first two node IDs. Because \c False is represented as "not 0040 * true" during evaluation, it actually stores \c Negated{true_node_id()} and 0041 * the deduplication table maps \c False to \c false_node_id() . 0042 * 0043 * \note The node classes use aggregate initialization so cannot be created 0044 * directly as \c Node variant classes using \c std::in_place_type . 0045 */ 0046 class CsgTree 0047 { 0048 public: 0049 //!@{ 0050 //! \name Type aliases 0051 using Node = orangeinp::Node; 0052 using NodeId = orangeinp::NodeId; 0053 using size_type = NodeId::size_type; 0054 using Insertion = std::pair<NodeId, bool>; 0055 using Simplification = std::optional<Node>; 0056 using VecNodeId = std::vector<NodeId>; 0057 //!@} 0058 0059 public: 0060 // Construct with no nodes except "true" and "false" 0061 CsgTree(); 0062 0063 // Add a node and return the new ID and whether it's unique 0064 Insertion insert(Node&& n); 0065 0066 // Add a surface ID and return the new ID 0067 inline Insertion insert(LocalSurfaceId s); 0068 0069 //! Number of nodes 0070 NodeId::size_type size() const { return nodes_.size(); } 0071 0072 // Get a node 0073 inline Node const& operator[](NodeId node_id) const; 0074 0075 // Replace a node with a logically equivalent one, simplifying 0076 Node exchange(NodeId node_id, Node&& n); 0077 0078 // Simplify a single node in-place [O(1)] 0079 Simplification simplify(NodeId); 0080 0081 // Insert a new volume which root is the node id 0082 inline void insert_volume(NodeId); 0083 0084 //! List of volumes defined in this tree 0085 VecNodeId const& volumes() const { return volumes_; } 0086 0087 //// STATIC HELPERS //// 0088 0089 //! Special ID of a node that's always 'true' 0090 static constexpr NodeId true_node_id() { return NodeId{0}; } 0091 //! Special ID of a node that's always 'false' 0092 static constexpr NodeId false_node_id() { return NodeId{1}; } 0093 0094 private: 0095 // Tree structure: nodes may have been simplified 0096 std::vector<Node> nodes_; 0097 0098 // Hashed nodes, both original and simplified 0099 std::unordered_map<Node, NodeId> ids_; 0100 0101 // CSG node of each volume 0102 VecNodeId volumes_; 0103 0104 //// HELPER FUNCTIONS //// 0105 0106 // Get a node (only this class can modify the node once added) 0107 Node& at(NodeId node_id); 0108 }; 0109 0110 //---------------------------------------------------------------------------// 0111 // FREE FUNCTIONS 0112 //---------------------------------------------------------------------------// 0113 // Print the tree's contents 0114 std::ostream& operator<<(std::ostream& os, CsgTree const&); 0115 0116 //---------------------------------------------------------------------------// 0117 // INLINE DEFINITIONS 0118 //---------------------------------------------------------------------------// 0119 /*! 0120 * Add a surface. 0121 */ 0122 auto CsgTree::insert(LocalSurfaceId s) -> Insertion 0123 { 0124 return this->insert(orangeinp::Surface{s}); 0125 } 0126 0127 //---------------------------------------------------------------------------// 0128 /*! 0129 * Insert a new volume which root is the node id. 0130 */ 0131 void CsgTree::insert_volume(NodeId node_id) 0132 { 0133 CELER_EXPECT(node_id < nodes_.size()); 0134 volumes_.push_back(std::move(node_id)); 0135 } 0136 0137 //---------------------------------------------------------------------------// 0138 /*! 0139 * Get a node by ID. 0140 */ 0141 auto CsgTree::operator[](NodeId node_id) const -> Node const& 0142 { 0143 CELER_EXPECT(node_id < nodes_.size()); 0144 return nodes_[node_id.unchecked_get()]; 0145 } 0146 0147 //---------------------------------------------------------------------------// 0148 } // namespace orangeinp 0149 } // 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 |