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_NodeId_HeaderFile
0015 #define _BRepGraph_NodeId_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
0033
0034
0035
0036 struct BRepGraph_NodeId
0037 {
0038
0039
0040
0041
0042
0043 enum class Kind : int
0044 {
0045 Solid = 0,
0046 Shell = 1,
0047 Face = 2,
0048 Wire = 3,
0049 Edge = 4,
0050 Vertex = 5,
0051 Compound = 6,
0052 CompSolid = 7,
0053 CoEdge = 8,
0054
0055 Product = 10,
0056 Occurrence = 11
0057 };
0058
0059
0060 static bool IsValidKind(const Kind theKind)
0061 {
0062 switch (theKind)
0063 {
0064 case Kind::Solid:
0065 case Kind::Shell:
0066 case Kind::Face:
0067 case Kind::Wire:
0068 case Kind::Edge:
0069 case Kind::Vertex:
0070 case Kind::Compound:
0071 case Kind::CompSolid:
0072 case Kind::CoEdge:
0073 case Kind::Product:
0074 case Kind::Occurrence:
0075 return true;
0076 }
0077 return false;
0078 }
0079
0080
0081
0082
0083
0084
0085
0086
0087 template <Kind TheKind>
0088 struct Typed
0089 {
0090 static constexpr uint32_t THE_START_INDEX = 0u;
0091 static constexpr uint32_t THE_INVALID_INDEX = std::numeric_limits<uint32_t>::max();
0092
0093 uint32_t Index;
0094
0095
0096 Typed()
0097 : Index(THE_INVALID_INDEX)
0098 {
0099 }
0100
0101
0102 explicit Typed(const uint32_t theIdx)
0103 : Index(theIdx)
0104 {
0105 }
0106
0107
0108 explicit Typed(const BRepGraph_NodeId theId)
0109 : Typed(FromNodeId(theId))
0110 {
0111 }
0112
0113 template <Kind OtherKind, typename std::enable_if_t<OtherKind != TheKind, int> = 0>
0114 Typed(const Typed<OtherKind>&) = delete;
0115
0116
0117 [[nodiscard]] static Typed Start() { return Typed(THE_START_INDEX); }
0118
0119
0120 [[nodiscard]] static Typed Invalid() { return Typed(); }
0121
0122
0123 [[nodiscard]] bool IsValid() const
0124 {
0125 return BRepGraph_NodeId::IsValidKind(TheKind) && Index != THE_INVALID_INDEX;
0126 }
0127
0128
0129
0130 [[nodiscard]] bool IsValid(const uint32_t theMaxCount) const
0131 {
0132 return IsValid() && Index < theMaxCount;
0133 }
0134
0135
0136 template <typename CountProviderT>
0137 [[nodiscard]] auto IsValidIn(const CountProviderT& theProvider) const
0138 -> decltype(theProvider.Nb(), bool())
0139 {
0140 return IsValid(theProvider.Nb());
0141 }
0142
0143
0144 template <typename CountProviderT>
0145 [[nodiscard]] auto IsValidIn(const CountProviderT& theProvider) const
0146 -> decltype(theProvider.Size(), bool())
0147 {
0148 return IsValid(static_cast<uint32_t>(theProvider.Size()));
0149 }
0150
0151
0152 operator BRepGraph_NodeId() const { return BRepGraph_NodeId(TheKind, Index); }
0153
0154
0155
0156
0157 static Typed FromNodeId(const BRepGraph_NodeId theId)
0158 {
0159 Standard_ASSERT_RETURN(theId.NodeKind == TheKind, "NodeId kind mismatch", Typed());
0160 if (!theId.IsValid())
0161 {
0162 return Typed();
0163 }
0164 return Typed(theId.Index);
0165 }
0166
0167 bool operator==(const Typed& theOther) const { return Index == theOther.Index; }
0168
0169 bool operator!=(const Typed& theOther) const { return Index != theOther.Index; }
0170
0171 bool operator<(const Typed& theOther) const { return Index < theOther.Index; }
0172
0173 bool operator<=(const Typed& theOther) const { return Index <= theOther.Index; }
0174
0175 bool operator>(const Typed& theOther) const { return Index > theOther.Index; }
0176
0177 bool operator>=(const Typed& theOther) const { return Index >= theOther.Index; }
0178
0179
0180 Typed& operator++()
0181 {
0182 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX, "pre-increment on invalid id");
0183 ++Index;
0184 return *this;
0185 }
0186
0187
0188 Typed operator++(int)
0189 {
0190 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX, "post-increment on invalid id");
0191 Typed aPrev = *this;
0192 ++Index;
0193 return aPrev;
0194 }
0195
0196
0197 [[nodiscard]] Typed operator+(const uint32_t theOffset) const
0198 {
0199 return Typed(Index + theOffset);
0200 }
0201
0202
0203 [[nodiscard]] Typed operator-(const uint32_t theOffset) const
0204 {
0205 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX && Index >= theOffset,
0206 "retreat underflows index");
0207 return Typed(Index - theOffset);
0208 }
0209
0210
0211 bool operator==(const BRepGraph_NodeId& theOther) const
0212 {
0213 return theOther.NodeKind == TheKind && theOther.Index == Index;
0214 }
0215
0216 bool operator!=(const BRepGraph_NodeId& theOther) const { return !(*this == theOther); }
0217
0218
0219 friend bool operator==(const BRepGraph_NodeId& theLhs, const Typed& theRhs)
0220 {
0221 return theRhs == theLhs;
0222 }
0223
0224 friend bool operator!=(const BRepGraph_NodeId& theLhs, const Typed& theRhs)
0225 {
0226 return theRhs != theLhs;
0227 }
0228
0229
0230 [[nodiscard]] bool IsRemoved(const BRepGraph& theGraph) const
0231 {
0232 return BRepGraph_NodeId(*this).IsRemoved(theGraph);
0233 }
0234
0235
0236 [[nodiscard]] bool IsOwned(const BRepGraph& theGraph) const
0237 {
0238 return BRepGraph_NodeId(*this).IsOwned(theGraph);
0239 }
0240 };
0241
0242
0243 static bool IsTopologyKind(const Kind theKind)
0244 {
0245 return IsValidKind(theKind) && theKind >= Kind::Solid && theKind <= Kind::CoEdge;
0246 }
0247
0248
0249 static bool IsAssemblyKind(const Kind theKind)
0250 {
0251 return IsValidKind(theKind) && (theKind == Kind::Product || theKind == Kind::Occurrence);
0252 }
0253
0254
0255
0256 static constexpr int THE_KIND_COUNT = static_cast<int>(Kind::Occurrence) + 1;
0257 static constexpr uint32_t THE_START_INDEX = 0u;
0258 static constexpr uint32_t THE_INVALID_INDEX = std::numeric_limits<uint32_t>::max();
0259
0260 Kind NodeKind;
0261 uint32_t Index;
0262
0263
0264
0265 BRepGraph_NodeId()
0266 : NodeKind(Kind::Solid),
0267 Index(THE_INVALID_INDEX)
0268 {
0269 }
0270
0271 BRepGraph_NodeId(const Kind theKind, const uint32_t theIdx)
0272 : NodeKind(theKind),
0273 Index(theIdx)
0274 {
0275 }
0276
0277
0278 [[nodiscard]] static BRepGraph_NodeId Start(const Kind theKind)
0279 {
0280 return BRepGraph_NodeId(theKind, THE_START_INDEX);
0281 }
0282
0283
0284 [[nodiscard]] static BRepGraph_NodeId Invalid(const Kind theKind = Kind::Solid)
0285 {
0286 return BRepGraph_NodeId(theKind, THE_INVALID_INDEX);
0287 }
0288
0289
0290 [[nodiscard]] bool IsValid() const { return IsValidKind(NodeKind) && Index != THE_INVALID_INDEX; }
0291
0292
0293
0294 [[nodiscard]] bool IsValid(const uint32_t theMaxCount) const
0295 {
0296 return IsValid() && Index < theMaxCount;
0297 }
0298
0299
0300 template <typename CountProviderT>
0301 [[nodiscard]] auto IsValidIn(const CountProviderT& theProvider) const
0302 -> decltype(theProvider.Nb(), bool())
0303 {
0304 return IsValid(theProvider.Nb());
0305 }
0306
0307
0308 template <typename CountProviderT>
0309 [[nodiscard]] auto IsValidIn(const CountProviderT& theProvider) const
0310 -> decltype(theProvider.Size(), bool())
0311 {
0312 return IsValid(static_cast<uint32_t>(theProvider.Size()));
0313 }
0314
0315 bool operator==(const BRepGraph_NodeId& theOther) const
0316 {
0317 return NodeKind == theOther.NodeKind && Index == theOther.Index;
0318 }
0319
0320 bool operator!=(const BRepGraph_NodeId& theOther) const { return !(*this == theOther); }
0321
0322 bool operator<(const BRepGraph_NodeId& theOther) const
0323 {
0324 if (NodeKind != theOther.NodeKind)
0325 {
0326 return static_cast<int>(NodeKind) < static_cast<int>(theOther.NodeKind);
0327 }
0328 return Index < theOther.Index;
0329 }
0330
0331
0332 BRepGraph_NodeId& operator++()
0333 {
0334 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX, "pre-increment on invalid id");
0335 ++Index;
0336 return *this;
0337 }
0338
0339
0340 BRepGraph_NodeId operator++(int)
0341 {
0342 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX, "post-increment on invalid id");
0343 BRepGraph_NodeId aPrev = *this;
0344 ++Index;
0345 return aPrev;
0346 }
0347
0348
0349 [[nodiscard]] BRepGraph_NodeId operator+(const uint32_t theOffset) const
0350 {
0351 return BRepGraph_NodeId(NodeKind, Index + theOffset);
0352 }
0353
0354
0355 [[nodiscard]] BRepGraph_NodeId operator-(const uint32_t theOffset) const
0356 {
0357 Standard_ASSERT_VOID(Index != THE_INVALID_INDEX && Index >= theOffset,
0358 "retreat underflows index");
0359 return BRepGraph_NodeId(NodeKind, Index - theOffset);
0360 }
0361
0362
0363 template <typename FuncT>
0364 static auto Visit(const BRepGraph_NodeId theNodeId, FuncT&& theFunc)
0365 -> decltype(std::forward<FuncT>(theFunc)(Typed<Kind::Vertex>()))
0366 {
0367 switch (theNodeId.NodeKind)
0368 {
0369 case Kind::Vertex:
0370 return std::forward<FuncT>(theFunc)(Typed<Kind::Vertex>::FromNodeId(theNodeId));
0371 case Kind::Edge:
0372 return std::forward<FuncT>(theFunc)(Typed<Kind::Edge>::FromNodeId(theNodeId));
0373 case Kind::CoEdge:
0374 return std::forward<FuncT>(theFunc)(Typed<Kind::CoEdge>::FromNodeId(theNodeId));
0375 case Kind::Wire:
0376 return std::forward<FuncT>(theFunc)(Typed<Kind::Wire>::FromNodeId(theNodeId));
0377 case Kind::Face:
0378 return std::forward<FuncT>(theFunc)(Typed<Kind::Face>::FromNodeId(theNodeId));
0379 case Kind::Shell:
0380 return std::forward<FuncT>(theFunc)(Typed<Kind::Shell>::FromNodeId(theNodeId));
0381 case Kind::Solid:
0382 return std::forward<FuncT>(theFunc)(Typed<Kind::Solid>::FromNodeId(theNodeId));
0383 case Kind::Compound:
0384 return std::forward<FuncT>(theFunc)(Typed<Kind::Compound>::FromNodeId(theNodeId));
0385 case Kind::CompSolid:
0386 return std::forward<FuncT>(theFunc)(Typed<Kind::CompSolid>::FromNodeId(theNodeId));
0387 case Kind::Product:
0388 return std::forward<FuncT>(theFunc)(Typed<Kind::Product>::FromNodeId(theNodeId));
0389 case Kind::Occurrence:
0390 return std::forward<FuncT>(theFunc)(Typed<Kind::Occurrence>::FromNodeId(theNodeId));
0391 }
0392
0393 Standard_ASSERT_VOID(false, "BRepGraph_NodeId::Visit: unhandled Kind");
0394 return std::forward<FuncT>(theFunc)(Typed<Kind::Vertex>());
0395 }
0396
0397
0398 [[nodiscard]] Standard_EXPORT bool IsRemoved(const BRepGraph& theGraph) const;
0399
0400
0401 [[nodiscard]] Standard_EXPORT bool IsOwned(const BRepGraph& theGraph) const;
0402 };
0403
0404
0405 using BRepGraph_SolidId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::Solid>;
0406 using BRepGraph_ShellId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::Shell>;
0407 using BRepGraph_FaceId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::Face>;
0408 using BRepGraph_WireId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::Wire>;
0409 using BRepGraph_EdgeId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::Edge>;
0410 using BRepGraph_VertexId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::Vertex>;
0411 using BRepGraph_CompoundId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::Compound>;
0412 using BRepGraph_CompSolidId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::CompSolid>;
0413 using BRepGraph_CoEdgeId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::CoEdge>;
0414 using BRepGraph_ProductId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::Product>;
0415 using BRepGraph_OccurrenceId = BRepGraph_NodeId::Typed<BRepGraph_NodeId::Kind::Occurrence>;
0416
0417
0418 template <>
0419 struct std::hash<BRepGraph_NodeId>
0420 {
0421 size_t operator()(const BRepGraph_NodeId& theId) const noexcept
0422 {
0423 size_t aCombination[2];
0424 aCombination[0] = opencascade::hash(static_cast<int>(theId.NodeKind));
0425 aCombination[1] = opencascade::hash(theId.Index);
0426 return opencascade::hashBytes(aCombination, sizeof(aCombination));
0427 }
0428 };
0429
0430
0431 template <BRepGraph_NodeId::Kind TheKind>
0432 struct std::hash<BRepGraph_NodeId::Typed<TheKind>>
0433 {
0434 size_t operator()(const BRepGraph_NodeId::Typed<TheKind>& theId) const noexcept
0435 {
0436 return std::hash<BRepGraph_NodeId>{}(static_cast<BRepGraph_NodeId>(theId));
0437 }
0438 };
0439
0440 #endif