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