File indexing completed on 2026-09-28 09:19:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _BRepGraph_RefId_HeaderFile
0015 #define _BRepGraph_RefId_HeaderFile
0016
0017 #include <Standard_Assert.hxx>
0018 #include <Standard_HashUtils.hxx>
0019
0020 #include <cstddef>
0021 #include <cstdint>
0022 #include <functional>
0023 #include <limits>
0024 #include <utility>
0025
0026 class BRepGraph;
0027
0028
0029
0030
0031
0032 struct BRepGraph_RefId
0033 {
0034
0035 enum class Kind : int
0036 {
0037 Shell = 0,
0038 Face = 1,
0039 Wire = 2,
0040 Vertex = 3,
0041 Solid = 4,
0042 Child = 5,
0043 Occurrence = 6
0044 };
0045
0046
0047 static bool IsValidKind(const Kind theKind)
0048 {
0049 switch (theKind)
0050 {
0051 case Kind::Shell:
0052 case Kind::Face:
0053 case Kind::Wire:
0054 case Kind::Vertex:
0055 case Kind::Solid:
0056 case Kind::Child:
0057 case Kind::Occurrence:
0058 return true;
0059 }
0060 return false;
0061 }
0062
0063
0064
0065
0066 template <Kind TheKind>
0067 struct Typed
0068 {
0069 static constexpr uint32_t THE_START_INDEX = 0u;
0070 static constexpr uint32_t THE_INVALID_INDEX = std::numeric_limits<uint32_t>::max();
0071
0072 uint32_t Index;
0073
0074 Typed()
0075 : Index(THE_INVALID_INDEX)
0076 {
0077 }
0078
0079 explicit Typed(const uint32_t theIdx)
0080 : Index(theIdx)
0081 {
0082 }
0083
0084
0085 explicit Typed(const BRepGraph_RefId theRefId)
0086 : Typed(FromRefId(theRefId))
0087 {
0088 }
0089
0090 template <Kind OtherKind, typename std::enable_if_t<OtherKind != TheKind, int> = 0>
0091 Typed(const Typed<OtherKind>&) = delete;
0092
0093
0094 [[nodiscard]] static Typed Start() { return Typed(THE_START_INDEX); }
0095
0096
0097 [[nodiscard]] static Typed Invalid() { return Typed(); }
0098
0099 [[nodiscard]] bool IsValid() const
0100 {
0101 return BRepGraph_RefId::IsValidKind(TheKind) && Index != THE_INVALID_INDEX;
0102 }
0103
0104
0105
0106 [[nodiscard]] bool IsValid(const uint32_t theMaxCount) const
0107 {
0108 return IsValid() && Index < theMaxCount;
0109 }
0110
0111 template <typename CountProviderT>
0112 [[nodiscard]] auto IsValidIn(const CountProviderT& theProvider) const
0113 -> decltype(theProvider.Nb(), bool())
0114 {
0115 return IsValid(theProvider.Nb());
0116 }
0117
0118 template <typename CountProviderT>
0119 [[nodiscard]] auto IsValidIn(const CountProviderT& theProvider) const
0120 -> decltype(theProvider.Size(), bool())
0121 {
0122 return IsValid(static_cast<uint32_t>(theProvider.Size()));
0123 }
0124
0125 operator BRepGraph_RefId() const { return BRepGraph_RefId(TheKind, Index); }
0126
0127 static Typed FromRefId(const BRepGraph_RefId theRefId)
0128 {
0129 Standard_ASSERT_RETURN(theRefId.RefKind == TheKind, "RefId kind mismatch", Typed());
0130 if (!theRefId.IsValid())
0131 {
0132 return Typed();
0133 }
0134 return Typed(theRefId.Index);
0135 }
0136
0137 bool operator==(const Typed& theOther) const { return Index == theOther.Index; }
0138
0139 bool operator!=(const Typed& theOther) const { return Index != theOther.Index; }
0140
0141 bool operator<(const Typed& theOther) const { return Index < theOther.Index; }
0142
0143 bool operator<=(const Typed& theOther) const { return Index <= theOther.Index; }
0144
0145 bool operator>(const Typed& theOther) const { return Index > theOther.Index; }
0146
0147 bool operator>=(const Typed& theOther) const { return Index >= theOther.Index; }
0148
0149
0150 Typed& operator++()
0151 {
0152 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX, "pre-increment on invalid id");
0153 ++Index;
0154 return *this;
0155 }
0156
0157
0158 Typed operator++(int)
0159 {
0160 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX, "post-increment on invalid id");
0161 Typed aPrev = *this;
0162 ++Index;
0163 return aPrev;
0164 }
0165
0166
0167 [[nodiscard]] Typed operator+(const uint32_t theOffset) const
0168 {
0169 return Typed(Index + theOffset);
0170 }
0171
0172
0173 [[nodiscard]] Typed operator-(const uint32_t theOffset) const
0174 {
0175 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX && Index >= theOffset,
0176 "retreat underflows index");
0177 return Typed(Index - theOffset);
0178 }
0179
0180 bool operator==(const BRepGraph_RefId& theOther) const
0181 {
0182 return theOther.RefKind == TheKind && theOther.Index == Index;
0183 }
0184
0185 bool operator!=(const BRepGraph_RefId& theOther) const { return !(*this == theOther); }
0186
0187 friend bool operator==(const BRepGraph_RefId& theLhs, const Typed& theRhs)
0188 {
0189 return theRhs == theLhs;
0190 }
0191
0192 friend bool operator!=(const BRepGraph_RefId& theLhs, const Typed& theRhs)
0193 {
0194 return theRhs != theLhs;
0195 }
0196
0197
0198 [[nodiscard]] bool IsRemoved(const BRepGraph& theGraph) const
0199 {
0200 return BRepGraph_RefId(*this).IsRemoved(theGraph);
0201 }
0202
0203
0204 [[nodiscard]] bool IsOwned(const BRepGraph& theGraph) const
0205 {
0206 return BRepGraph_RefId(*this).IsOwned(theGraph);
0207 }
0208 };
0209
0210 static bool IsTopologyRefKind(const Kind theKind)
0211 {
0212 return IsValidKind(theKind) && theKind >= Kind::Shell && theKind <= Kind::Child;
0213 }
0214
0215 static constexpr uint32_t THE_START_INDEX = 0u;
0216 static constexpr uint32_t THE_INVALID_INDEX = std::numeric_limits<uint32_t>::max();
0217
0218 Kind RefKind;
0219 uint32_t Index;
0220
0221 BRepGraph_RefId()
0222 : RefKind(Kind::Shell),
0223 Index(THE_INVALID_INDEX)
0224 {
0225 }
0226
0227 BRepGraph_RefId(const Kind theKind, const uint32_t theIdx)
0228 : RefKind(theKind),
0229 Index(theIdx)
0230 {
0231 }
0232
0233
0234 [[nodiscard]] static BRepGraph_RefId Start(const Kind theKind)
0235 {
0236 return BRepGraph_RefId(theKind, THE_START_INDEX);
0237 }
0238
0239
0240 [[nodiscard]] static BRepGraph_RefId Invalid(const Kind theKind = Kind::Shell)
0241 {
0242 return BRepGraph_RefId(theKind, THE_INVALID_INDEX);
0243 }
0244
0245 [[nodiscard]] bool IsValid() const { return IsValidKind(RefKind) && Index != THE_INVALID_INDEX; }
0246
0247
0248
0249 [[nodiscard]] bool IsValid(const uint32_t theMaxCount) const
0250 {
0251 return IsValid() && Index < theMaxCount;
0252 }
0253
0254 template <typename CountProviderT>
0255 [[nodiscard]] auto IsValidIn(const CountProviderT& theProvider) const
0256 -> decltype(theProvider.Nb(), bool())
0257 {
0258 return IsValid(theProvider.Nb());
0259 }
0260
0261 template <typename CountProviderT>
0262 [[nodiscard]] auto IsValidIn(const CountProviderT& theProvider) const
0263 -> decltype(theProvider.Size(), bool())
0264 {
0265 return IsValid(static_cast<uint32_t>(theProvider.Size()));
0266 }
0267
0268 bool operator==(const BRepGraph_RefId& theOther) const
0269 {
0270 return RefKind == theOther.RefKind && Index == theOther.Index;
0271 }
0272
0273 bool operator!=(const BRepGraph_RefId& theOther) const { return !(*this == theOther); }
0274
0275 bool operator<(const BRepGraph_RefId& theOther) const
0276 {
0277 if (RefKind != theOther.RefKind)
0278 {
0279 return static_cast<int>(RefKind) < static_cast<int>(theOther.RefKind);
0280 }
0281 return Index < theOther.Index;
0282 }
0283
0284
0285 BRepGraph_RefId& operator++()
0286 {
0287 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX, "pre-increment on invalid id");
0288 ++Index;
0289 return *this;
0290 }
0291
0292
0293 BRepGraph_RefId operator++(int)
0294 {
0295 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX, "post-increment on invalid id");
0296 BRepGraph_RefId aPrev = *this;
0297 ++Index;
0298 return aPrev;
0299 }
0300
0301
0302 [[nodiscard]] BRepGraph_RefId operator+(const uint32_t theOffset) const
0303 {
0304 return BRepGraph_RefId(RefKind, Index + theOffset);
0305 }
0306
0307
0308 [[nodiscard]] BRepGraph_RefId operator-(const uint32_t theOffset) const
0309 {
0310 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX && Index >= theOffset,
0311 "retreat underflows index");
0312 return BRepGraph_RefId(RefKind, Index - theOffset);
0313 }
0314
0315
0316 template <typename FuncT>
0317 static auto Visit(const BRepGraph_RefId theRefId, FuncT&& theFunc)
0318 -> decltype(std::forward<FuncT>(theFunc)(Typed<Kind::Shell>()))
0319 {
0320 switch (theRefId.RefKind)
0321 {
0322 case Kind::Shell:
0323 return std::forward<FuncT>(theFunc)(Typed<Kind::Shell>::FromRefId(theRefId));
0324 case Kind::Face:
0325 return std::forward<FuncT>(theFunc)(Typed<Kind::Face>::FromRefId(theRefId));
0326 case Kind::Wire:
0327 return std::forward<FuncT>(theFunc)(Typed<Kind::Wire>::FromRefId(theRefId));
0328 case Kind::Vertex:
0329 return std::forward<FuncT>(theFunc)(Typed<Kind::Vertex>::FromRefId(theRefId));
0330 case Kind::Solid:
0331 return std::forward<FuncT>(theFunc)(Typed<Kind::Solid>::FromRefId(theRefId));
0332 case Kind::Child:
0333 return std::forward<FuncT>(theFunc)(Typed<Kind::Child>::FromRefId(theRefId));
0334 case Kind::Occurrence:
0335 return std::forward<FuncT>(theFunc)(Typed<Kind::Occurrence>::FromRefId(theRefId));
0336 }
0337
0338 Standard_ASSERT_VOID(false, "BRepGraph_RefId::Visit: unhandled Kind");
0339 return std::forward<FuncT>(theFunc)(Typed<Kind::Shell>());
0340 }
0341
0342
0343 [[nodiscard]] Standard_EXPORT bool IsRemoved(const BRepGraph& theGraph) const;
0344
0345
0346 [[nodiscard]] Standard_EXPORT bool IsOwned(const BRepGraph& theGraph) const;
0347 };
0348
0349 using BRepGraph_ShellRefId = BRepGraph_RefId::Typed<BRepGraph_RefId::Kind::Shell>;
0350 using BRepGraph_FaceRefId = BRepGraph_RefId::Typed<BRepGraph_RefId::Kind::Face>;
0351 using BRepGraph_WireRefId = BRepGraph_RefId::Typed<BRepGraph_RefId::Kind::Wire>;
0352 using BRepGraph_VertexRefId = BRepGraph_RefId::Typed<BRepGraph_RefId::Kind::Vertex>;
0353 using BRepGraph_SolidRefId = BRepGraph_RefId::Typed<BRepGraph_RefId::Kind::Solid>;
0354 using BRepGraph_ChildRefId = BRepGraph_RefId::Typed<BRepGraph_RefId::Kind::Child>;
0355 using BRepGraph_OccurrenceRefId = BRepGraph_RefId::Typed<BRepGraph_RefId::Kind::Occurrence>;
0356
0357 template <>
0358 struct std::hash<BRepGraph_RefId>
0359 {
0360 size_t operator()(const BRepGraph_RefId& theId) const noexcept
0361 {
0362 size_t aCombination[2];
0363 aCombination[0] = opencascade::hash(static_cast<int>(theId.RefKind));
0364 aCombination[1] = opencascade::hash(theId.Index);
0365 return opencascade::hashBytes(aCombination, sizeof(aCombination));
0366 }
0367 };
0368
0369 template <BRepGraph_RefId::Kind TheKind>
0370 struct std::hash<BRepGraph_RefId::Typed<TheKind>>
0371 {
0372 size_t operator()(const BRepGraph_RefId::Typed<TheKind>& theId) const noexcept
0373 {
0374 return std::hash<BRepGraph_RefId>{}(static_cast<BRepGraph_RefId>(theId));
0375 }
0376 };
0377
0378 #endif