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