File indexing completed on 2026-09-28 09:19:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _BRepGraph_ItemUID_HeaderFile
0015 #define _BRepGraph_ItemUID_HeaderFile
0016
0017 #include <BRepGraph_NodeId.hxx>
0018 #include <BRepGraph_RefId.hxx>
0019 #include <Standard_Assert.hxx>
0020 #include <Standard_HashUtils.hxx>
0021
0022 #include <cstdint>
0023 #include <cstddef>
0024 #include <functional>
0025 #include <limits>
0026
0027
0028
0029
0030
0031
0032 class BRepGraph_ItemUID
0033 {
0034 public:
0035
0036 enum class Domain : uint8_t
0037 {
0038 None,
0039 Node,
0040 Reference
0041 };
0042
0043
0044 BRepGraph_ItemUID() = default;
0045
0046
0047 static BRepGraph_ItemUID Node(const BRepGraph_NodeId::Kind theKind, const size_t theCounter)
0048 {
0049 return BRepGraph_ItemUID(Domain::Node, static_cast<uint8_t>(theKind), theCounter);
0050 }
0051
0052
0053 static BRepGraph_ItemUID Reference(const BRepGraph_RefId::Kind theKind, const size_t theCounter)
0054 {
0055 return BRepGraph_ItemUID(Domain::Reference, static_cast<uint8_t>(theKind), theCounter);
0056 }
0057
0058
0059 static BRepGraph_ItemUID Invalid() { return BRepGraph_ItemUID(); }
0060
0061
0062 [[nodiscard]] bool IsValid() const noexcept
0063 {
0064 if (myCounter == 0)
0065 {
0066 return false;
0067 }
0068
0069 switch (myDomain)
0070 {
0071 case Domain::Node:
0072 return BRepGraph_NodeId::IsValidKind(static_cast<BRepGraph_NodeId::Kind>(myKind));
0073 case Domain::Reference:
0074 return BRepGraph_RefId::IsValidKind(static_cast<BRepGraph_RefId::Kind>(myKind));
0075 case Domain::None:
0076 return false;
0077 }
0078 return false;
0079 }
0080
0081
0082 [[nodiscard]] Domain ItemDomain() const noexcept { return myDomain; }
0083
0084 [[nodiscard]] bool IsNode() const noexcept { return myDomain == Domain::Node; }
0085
0086 [[nodiscard]] bool IsReference() const noexcept { return myDomain == Domain::Reference; }
0087
0088
0089 [[nodiscard]] BRepGraph_NodeId::Kind NodeKind() const noexcept
0090 {
0091 Standard_ASSERT_RETURN(
0092 IsNode() && BRepGraph_NodeId::IsValidKind(static_cast<BRepGraph_NodeId::Kind>(myKind)),
0093 "BRepGraph_ItemUID::NodeKind(): UID is not a valid node UID",
0094 BRepGraph_NodeId::Kind::Solid);
0095 return static_cast<BRepGraph_NodeId::Kind>(myKind);
0096 }
0097
0098
0099 [[nodiscard]] BRepGraph_RefId::Kind RefKind() const noexcept
0100 {
0101 Standard_ASSERT_RETURN(
0102 IsReference() && BRepGraph_RefId::IsValidKind(static_cast<BRepGraph_RefId::Kind>(myKind)),
0103 "BRepGraph_ItemUID::RefKind(): UID is not a valid reference UID",
0104 BRepGraph_RefId::Kind::Shell);
0105 return static_cast<BRepGraph_RefId::Kind>(myKind);
0106 }
0107
0108
0109 [[nodiscard]] uint8_t RawKind() const noexcept { return myKind; }
0110
0111
0112 [[nodiscard]] size_t Counter() const noexcept { return myCounter; }
0113
0114 friend bool operator==(const BRepGraph_ItemUID& theLeft,
0115 const BRepGraph_ItemUID& theRight) noexcept
0116 {
0117 if (theLeft.myCounter == 0 || theRight.myCounter == 0)
0118 {
0119 return (theLeft.myCounter == 0) == (theRight.myCounter == 0);
0120 }
0121 return theLeft.myDomain == theRight.myDomain && theLeft.myKind == theRight.myKind
0122 && theLeft.myCounter == theRight.myCounter;
0123 }
0124
0125 friend bool operator!=(const BRepGraph_ItemUID& theLeft,
0126 const BRepGraph_ItemUID& theRight) noexcept
0127 {
0128 return !(theLeft == theRight);
0129 }
0130
0131 friend bool operator<(const BRepGraph_ItemUID& theLeft,
0132 const BRepGraph_ItemUID& theRight) noexcept
0133 {
0134 if (theLeft.myDomain != theRight.myDomain)
0135 {
0136 return static_cast<uint8_t>(theLeft.myDomain) < static_cast<uint8_t>(theRight.myDomain);
0137 }
0138 if (theLeft.myKind != theRight.myKind)
0139 {
0140 return theLeft.myKind < theRight.myKind;
0141 }
0142 return theLeft.myCounter < theRight.myCounter;
0143 }
0144
0145
0146 [[nodiscard]] size_t HashValue() const noexcept
0147 {
0148 if (myCounter == 0)
0149 {
0150 return opencascade::hash(0);
0151 }
0152
0153 size_t aCombination[3];
0154 aCombination[0] = opencascade::hash(static_cast<uint32_t>(myDomain));
0155 aCombination[1] = opencascade::hash(static_cast<uint32_t>(myKind));
0156 aCombination[2] = opencascade::hash(myCounter);
0157 return opencascade::hashBytes(aCombination, sizeof(aCombination));
0158 }
0159
0160 private:
0161 BRepGraph_ItemUID(const Domain theDomain, const uint8_t theKind, const size_t theCounter)
0162 : myCounter(0),
0163 myDomain(theDomain),
0164 myKind(theKind)
0165 {
0166 Standard_ASSERT_VOID(theCounter > 0, "BRepGraph_ItemUID: counter must be > 0 for valid UIDs");
0167 Standard_ASSERT_VOID(theCounter <= std::numeric_limits<uint32_t>::max(),
0168 "BRepGraph_ItemUID: counter exceeds 32-bit storage");
0169 if (theCounter > 0 && theCounter <= std::numeric_limits<uint32_t>::max())
0170 {
0171 myCounter = static_cast<uint32_t>(theCounter);
0172 }
0173 }
0174
0175 uint32_t myCounter = 0;
0176 Domain myDomain = Domain::None;
0177 uint8_t myKind = 0;
0178 };
0179
0180 static_assert(sizeof(BRepGraph_ItemUID) <= 8, "BRepGraph_ItemUID must stay compact");
0181
0182
0183 template <>
0184 struct std::hash<BRepGraph_ItemUID>
0185 {
0186 size_t operator()(const BRepGraph_ItemUID& theUID) const noexcept { return theUID.HashValue(); }
0187 };
0188
0189 #endif