Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-28 09:19:37

0001 // Copyright (c) 2026 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef _BRepGraph_ReverseIterator_HeaderFile
0015 #define _BRepGraph_ReverseIterator_HeaderFile
0016 
0017 #include <BRepGraph.hxx>
0018 #include <BRepGraph_RefsIterator.hxx>
0019 #include <BRepGraph_RefsView.hxx>
0020 #include <BRepGraph_TopoView.hxx>
0021 #include <NCollection_ForwardRange.hxx>
0022 #include <NCollection_LinearVector.hxx>
0023 #include <type_traits>
0024 
0025 //! @brief Single-level typed iterators over parent definitions via relation lists.
0026 //!
0027 //! These iterators wrap parent relation containers returned by TopoView accessors,
0028 //! or derive parent definitions from const relation storage such as EdgeRelations::CoEdgeIds.
0029 //! They provide a typed, skip-removed iteration pattern consistent with the
0030 //! forward iterators in BRepGraph_DefsIterator and BRepGraph_RefsIterator.
0031 //!
0032 //! Usage:
0033 //! @code
0034 //!   // Traditional iteration:
0035 //!   for (BRepGraph_FacesOfEdge anIt(aGraph, anEdgeId); anIt.More(); anIt.Next())
0036 //!   {
0037 //!     const BRepGraph_FaceId aFaceId = anIt.CurrentId();
0038 //!   }
0039 //!
0040 //!   // Range-based for:
0041 //!   for (const BRepGraph_FaceId aFaceId : BRepGraph_FacesOfEdge(aGraph, anEdgeId))
0042 //!   {
0043 //!     // ...
0044 //!   }
0045 //! @endcode
0046 namespace BRepGraph_ReverseIterator
0047 {
0048 
0049 //! Compile-time traits mapping typed ID to its definition type and accessor.
0050 template <typename TypedIdT>
0051 struct DefTraits;
0052 
0053 template <>
0054 struct DefTraits<BRepGraph_SolidId>
0055 {
0056   using DefType = BRepGraphInc::SolidDef;
0057 
0058   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_SolidId theId)
0059   {
0060     return theGraph.Topo().Solids().Definition(theId);
0061   }
0062 };
0063 
0064 template <>
0065 struct DefTraits<BRepGraph_ShellId>
0066 {
0067   using DefType = BRepGraphInc::ShellDef;
0068 
0069   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_ShellId theId)
0070   {
0071     return theGraph.Topo().Shells().Definition(theId);
0072   }
0073 };
0074 
0075 template <>
0076 struct DefTraits<BRepGraph_FaceId>
0077 {
0078   using DefType = BRepGraphInc::FaceDef;
0079 
0080   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_FaceId theId)
0081   {
0082     return theGraph.Topo().Faces().Definition(theId);
0083   }
0084 };
0085 
0086 template <>
0087 struct DefTraits<BRepGraph_WireId>
0088 {
0089   using DefType = BRepGraphInc::WireDef;
0090 
0091   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_WireId theId)
0092   {
0093     return theGraph.Topo().Wires().Definition(theId);
0094   }
0095 };
0096 
0097 template <>
0098 struct DefTraits<BRepGraph_EdgeId>
0099 {
0100   using DefType = BRepGraphInc::EdgeDef;
0101 
0102   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_EdgeId theId)
0103   {
0104     return theGraph.Topo().Edges().Definition(theId);
0105   }
0106 };
0107 
0108 template <>
0109 struct DefTraits<BRepGraph_VertexId>
0110 {
0111   using DefType = BRepGraphInc::VertexDef;
0112 
0113   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_VertexId theId)
0114   {
0115     return theGraph.Topo().Vertices().Definition(theId);
0116   }
0117 };
0118 
0119 template <>
0120 struct DefTraits<BRepGraph_CoEdgeId>
0121 {
0122   using DefType = BRepGraphInc::CoEdgeDef;
0123 
0124   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_CoEdgeId theId)
0125   {
0126     return theGraph.Topo().CoEdges().Definition(theId);
0127   }
0128 };
0129 
0130 template <>
0131 struct DefTraits<BRepGraph_CompoundId>
0132 {
0133   using DefType = BRepGraphInc::CompoundDef;
0134 
0135   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_CompoundId theId)
0136   {
0137     return theGraph.Topo().Compounds().Definition(theId);
0138   }
0139 };
0140 
0141 template <>
0142 struct DefTraits<BRepGraph_CompSolidId>
0143 {
0144   using DefType = BRepGraphInc::CompSolidDef;
0145 
0146   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_CompSolidId theId)
0147   {
0148     return theGraph.Topo().CompSolids().Definition(theId);
0149   }
0150 };
0151 
0152 template <>
0153 struct DefTraits<BRepGraph_ProductId>
0154 {
0155   using DefType = BRepGraphInc::ProductDef;
0156 
0157   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_ProductId theId)
0158   {
0159     return theGraph.Topo().Products().Definition(theId);
0160   }
0161 };
0162 
0163 template <>
0164 struct DefTraits<BRepGraph_OccurrenceId>
0165 {
0166   using DefType = BRepGraphInc::OccurrenceDef;
0167 
0168   static const DefType& Get(const BRepGraph& theGraph, const BRepGraph_OccurrenceId theId)
0169   {
0170     return theGraph.Topo().Occurrences().Definition(theId);
0171   }
0172 };
0173 
0174 //! Typed iterator over a relation vector of parent IDs.
0175 //! Skips removed parent definitions automatically in sequential iteration.
0176 //! Also provides indexed access (Length/Value) for callers that need
0177 //! random access into the underlying vector (e.g. BRepGraph_ParentExplorer).
0178 //! @tparam TypedIdT Typed ID such as BRepGraph_FaceId, BRepGraph_EdgeId, etc.
0179 template <typename TypedIdT, typename ContainerT = NCollection_LinearVector<TypedIdT>>
0180 class ParentsOf
0181 {
0182 public:
0183   ParentsOf(const BRepGraph& theGraph, const ContainerT& theParents)
0184       : myGraph(&theGraph),
0185         myParents(&theParents),
0186         myNbParents(theGraph.Topo().Gen().Nb(BRepGraph_NodeId(TypedIdT()).NodeKind))
0187   {
0188     skipRemoved();
0189   }
0190 
0191   //! Construct starting at a given vector index (for resumable iteration).
0192   //! Skips to the first non-removed entry at or after theStartIndex.
0193   ParentsOf(const BRepGraph& theGraph, const ContainerT& theParents, const uint32_t theStartIndex)
0194       : myGraph(&theGraph),
0195         myParents(&theParents),
0196         myNbParents(theGraph.Topo().Gen().Nb(BRepGraph_NodeId(TypedIdT()).NodeKind)),
0197         myIndex(theStartIndex)
0198   {
0199     skipRemoved();
0200   }
0201 
0202   [[nodiscard]] bool More() const { return myIndex < static_cast<uint32_t>(myParents->Size()); }
0203 
0204   void Next()
0205   {
0206     ++myIndex;
0207     skipRemoved();
0208   }
0209 
0210   [[nodiscard]] TypedIdT CurrentId() const
0211   {
0212     return myParents->Value(static_cast<size_t>(myIndex));
0213   }
0214 
0215   //! Alias for CurrentId(), enables range-for via NCollection_ForwardRange Current() priority.
0216   [[nodiscard]] TypedIdT Current() const { return CurrentId(); }
0217 
0218   //! Current parent definition (typed lookup via DefTraits).
0219   [[nodiscard]] const typename DefTraits<TypedIdT>::DefType& Definition() const
0220   {
0221     return DefTraits<TypedIdT>::Get(*myGraph, CurrentId());
0222   }
0223 
0224   [[nodiscard]] uint32_t Index() const { return myIndex; }
0225 
0226   [[nodiscard]] size_t Size() const { return myParents->Size(); }
0227 
0228   //! Returns the parent ID at the given bucket index (does NOT check removal status).
0229   [[nodiscard]] TypedIdT Value(const size_t theIndex) const { return myParents->Value(theIndex); }
0230 
0231   //! Returns an STL-compatible iterator for range-based for loops.
0232   NCollection_ForwardRangeIterator<ParentsOf> begin()
0233   {
0234     return NCollection_ForwardRangeIterator<ParentsOf>(this);
0235   }
0236 
0237   //! Returns a sentinel marking the end of iteration.
0238   NCollection_ForwardRangeSentinel end() const { return NCollection_ForwardRangeSentinel{}; }
0239 
0240 private:
0241   void skipRemoved()
0242   {
0243     while (myIndex < static_cast<uint32_t>(myParents->Size()))
0244     {
0245       const TypedIdT aParentId = myParents->Value(static_cast<size_t>(myIndex));
0246       if (aParentId.IsValid(myNbParents) && !aParentId.IsRemoved(*myGraph))
0247       {
0248         return;
0249       }
0250       ++myIndex;
0251     }
0252   }
0253 
0254   const BRepGraph*  myGraph     = nullptr;
0255   const ContainerT* myParents   = nullptr;
0256   uint32_t          myNbParents = 0;
0257   uint32_t          myIndex     = 0;
0258 };
0259 
0260 template <typename TraitsT>
0261 class EdgeParentsOf
0262 {
0263 public:
0264   using ParentId = typename TraitsT::ParentId;
0265 
0266   EdgeParentsOf(const BRepGraph& theGraph, const BRepGraph_EdgeId theEdge)
0267       : myGraph(&theGraph),
0268         myEdge(theEdge)
0269   {
0270     init();
0271     advance();
0272   }
0273 
0274   //! Construct starting at a given coedge relation index (for resumable iteration).
0275   EdgeParentsOf(const BRepGraph&       theGraph,
0276                 const BRepGraph_EdgeId theEdge,
0277                 const uint32_t         theStartIndex)
0278       : myGraph(&theGraph),
0279         myEdge(theEdge),
0280         myIndex(theStartIndex)
0281   {
0282     init();
0283     advance();
0284   }
0285 
0286   [[nodiscard]] bool More() const { return myHasCurrent; }
0287 
0288   void Next()
0289   {
0290     ++myIndex;
0291     advance();
0292   }
0293 
0294   [[nodiscard]] ParentId CurrentId() const { return myCurrent; }
0295 
0296   [[nodiscard]] ParentId Current() const { return CurrentId(); }
0297 
0298   [[nodiscard]] const typename DefTraits<ParentId>::DefType& Definition() const
0299   {
0300     return DefTraits<ParentId>::Get(*myGraph, CurrentId());
0301   }
0302 
0303   [[nodiscard]] uint32_t Index() const { return myIndex; }
0304 
0305   NCollection_ForwardRangeIterator<EdgeParentsOf> begin()
0306   {
0307     return NCollection_ForwardRangeIterator<EdgeParentsOf>(this);
0308   }
0309 
0310   NCollection_ForwardRangeSentinel end() const { return NCollection_ForwardRangeSentinel{}; }
0311 
0312 private:
0313   void init()
0314   {
0315     if (!myEdge.IsValid(myGraph->Topo().Edges().Nb()) || myEdge.IsRemoved(*myGraph))
0316     {
0317       return;
0318     }
0319     myNbParents = TraitsT::NbParents(*myGraph);
0320     myCoEdges   = &myGraph->Topo().Edges().CoEdges(myEdge);
0321   }
0322 
0323   [[nodiscard]] ParentId parentAt(const uint32_t theIndex) const
0324   {
0325     if (myCoEdges == nullptr || theIndex >= static_cast<uint32_t>(myCoEdges->Size()))
0326     {
0327       return ParentId();
0328     }
0329     const BRepGraph_CoEdgeId aCoEdgeId = myCoEdges->Value(static_cast<size_t>(theIndex));
0330     if (!aCoEdgeId.IsValid(myGraph->Topo().CoEdges().Nb()) || aCoEdgeId.IsRemoved(*myGraph))
0331     {
0332       return ParentId();
0333     }
0334 
0335     const BRepGraphInc::CoEdgeDef& aCoEdge = myGraph->Topo().CoEdges().Definition(aCoEdgeId);
0336     const ParentId                 aParent = TraitsT::ParentIdOf(aCoEdge);
0337     if (!aParent.IsValid(myNbParents) || aParent.IsRemoved(*myGraph))
0338     {
0339       return ParentId();
0340     }
0341     return aParent;
0342   }
0343 
0344   [[nodiscard]] bool isFirstOccurrence(const ParentId theParent, const uint32_t theIndex) const
0345   {
0346     for (uint32_t anIndex = 0; anIndex < theIndex; ++anIndex)
0347     {
0348       if (parentAt(anIndex) == theParent)
0349       {
0350         return false;
0351       }
0352     }
0353     return true;
0354   }
0355 
0356   void advance()
0357   {
0358     myHasCurrent = false;
0359     if (myCoEdges == nullptr)
0360     {
0361       return;
0362     }
0363 
0364     while (myIndex < static_cast<uint32_t>(myCoEdges->Size()))
0365     {
0366       const ParentId aParent = parentAt(myIndex);
0367       if (aParent.IsValid() && isFirstOccurrence(aParent, myIndex))
0368       {
0369         myCurrent    = aParent;
0370         myHasCurrent = true;
0371         return;
0372       }
0373       ++myIndex;
0374     }
0375   }
0376 
0377   const BRepGraph*                                    myGraph = nullptr;
0378   BRepGraph_EdgeId                                    myEdge;
0379   const NCollection_LinearVector<BRepGraph_CoEdgeId>* myCoEdges = nullptr;
0380   ParentId                                            myCurrent;
0381   uint32_t                                            myNbParents  = 0;
0382   uint32_t                                            myIndex      = 0;
0383   bool                                                myHasCurrent = false;
0384 };
0385 
0386 //! Result pair returned by parent-ref iterators: parent definition ID + the RefId
0387 //! in that parent which references the child.
0388 template <typename ParentIdT, typename RefIdT>
0389 struct ParentRef
0390 {
0391   ParentIdT ParentId;
0392   RefIdT    Ref;
0393 };
0394 
0395 //! Typed iterator over parent ID relation lists that also resolves the specific
0396 //! RefId linking each parent to the child by lookup in the parent definition.
0397 //! Used only where the reverse relation stores parent IDs but no ref IDs.
0398 //! @tparam TraitsT Traits with: ParentId, ChildId, RefId types,
0399 //!   FindRef(graph, parentId, childId) -> RefId (invalid if not found)
0400 template <typename TraitsT>
0401 class LookupParentRefsOf
0402 {
0403 public:
0404   using ParentIdType  = typename TraitsT::ParentId;
0405   using ChildIdType   = typename TraitsT::ChildId;
0406   using RefIdType     = typename TraitsT::RefId;
0407   using ResultType    = ParentRef<ParentIdType, RefIdType>;
0408   using ContainerType = typename TraitsT::ContainerType;
0409 
0410   LookupParentRefsOf(const BRepGraph&     theGraph,
0411                      const ContainerType& theParents,
0412                      const ChildIdType    theChild)
0413       : myGraph(&theGraph),
0414         myParents(&theParents),
0415         myChild(theChild),
0416         myNbParents(theGraph.Topo().Gen().Nb(BRepGraph_NodeId(ParentIdType()).NodeKind)),
0417         myNbRefs([&]() {
0418           if constexpr (std::is_convertible_v<RefIdType, BRepGraph_NodeId>)
0419           {
0420             return theGraph.Topo().Gen().Nb(BRepGraph_NodeId(RefIdType()).NodeKind);
0421           }
0422           else
0423           {
0424             return theGraph.Refs().Gen().Nb(BRepGraph_RefId(RefIdType()).RefKind);
0425           }
0426         }())
0427   {
0428     advance();
0429   }
0430 
0431   [[nodiscard]] bool More() const { return myHasCurrent; }
0432 
0433   void Next()
0434   {
0435     ++myIndex;
0436     advance();
0437   }
0438 
0439   [[nodiscard]] ResultType Current() const { return myCurrent; }
0440 
0441   [[nodiscard]] ParentIdType CurrentParentId() const { return myCurrent.ParentId; }
0442 
0443   [[nodiscard]] RefIdType CurrentRefId() const { return myCurrent.Ref; }
0444 
0445   [[nodiscard]] uint32_t Index() const { return myIndex; }
0446 
0447   //! Returns an STL-compatible iterator for range-based for loops.
0448   NCollection_ForwardRangeIterator<LookupParentRefsOf> begin()
0449   {
0450     return NCollection_ForwardRangeIterator<LookupParentRefsOf>(this);
0451   }
0452 
0453   //! Returns a sentinel marking the end of iteration.
0454   NCollection_ForwardRangeSentinel end() const { return NCollection_ForwardRangeSentinel{}; }
0455 
0456 private:
0457   void advance()
0458   {
0459     myHasCurrent = false;
0460     while (myIndex < static_cast<uint32_t>(myParents->Size()))
0461     {
0462       const ParentIdType aParentId = myParents->Value(static_cast<size_t>(myIndex));
0463       if (aParentId.IsValid(myNbParents) && !aParentId.IsRemoved(*myGraph))
0464       {
0465         const RefIdType aRefId = TraitsT::FindRef(*myGraph, aParentId, myChild);
0466         if (aRefId.IsValid(myNbRefs) && !aRefId.IsRemoved(*myGraph))
0467         {
0468           myCurrent    = ResultType{aParentId, aRefId};
0469           myHasCurrent = true;
0470           return;
0471         }
0472       }
0473       ++myIndex;
0474     }
0475   }
0476 
0477   const BRepGraph*     myGraph   = nullptr;
0478   const ContainerType* myParents = nullptr;
0479   ChildIdType          myChild;
0480   ResultType           myCurrent;
0481   uint32_t             myNbParents  = 0;
0482   uint32_t             myNbRefs     = 0;
0483   uint32_t             myIndex      = 0;
0484   bool                 myHasCurrent = false;
0485 };
0486 
0487 template <typename TraitsT>
0488 class IdsOfRefs
0489 {
0490 public:
0491   using IdType        = typename TraitsT::IdType;
0492   using RefIdType     = typename TraitsT::RefIdType;
0493   using ContainerType = typename TraitsT::ContainerType;
0494 
0495   IdsOfRefs(const BRepGraph& theGraph, const ContainerType& theRefs)
0496       : myGraph(&theGraph),
0497         myRefs(&theRefs),
0498         myNbRefs(theGraph.Refs().Gen().Nb(BRepGraph_RefId(RefIdType()).RefKind)),
0499         myNbIds(theGraph.Topo().Gen().Nb(BRepGraph_NodeId(IdType()).NodeKind))
0500   {
0501     advance();
0502   }
0503 
0504   IdsOfRefs(const BRepGraph& theGraph, const ContainerType& theRefs, const uint32_t theStartIndex)
0505       : myGraph(&theGraph),
0506         myRefs(&theRefs),
0507         myNbRefs(theGraph.Refs().Gen().Nb(BRepGraph_RefId(RefIdType()).RefKind)),
0508         myNbIds(theGraph.Topo().Gen().Nb(BRepGraph_NodeId(IdType()).NodeKind)),
0509         myIndex(theStartIndex)
0510   {
0511     advance();
0512   }
0513 
0514   [[nodiscard]] bool More() const { return myHasCurrent; }
0515 
0516   void Next()
0517   {
0518     ++myIndex;
0519     advance();
0520   }
0521 
0522   [[nodiscard]] IdType CurrentId() const { return myCurrent; }
0523 
0524   [[nodiscard]] IdType CurrentParentId() const { return CurrentId(); }
0525 
0526   [[nodiscard]] RefIdType CurrentRefId() const { return myCurrentRef; }
0527 
0528   [[nodiscard]] IdType Current() const { return CurrentId(); }
0529 
0530   [[nodiscard]] const typename DefTraits<IdType>::DefType& Definition() const
0531   {
0532     return DefTraits<IdType>::Get(*myGraph, CurrentId());
0533   }
0534 
0535   [[nodiscard]] uint32_t Index() const { return myIndex; }
0536 
0537   NCollection_ForwardRangeIterator<IdsOfRefs> begin()
0538   {
0539     return NCollection_ForwardRangeIterator<IdsOfRefs>(this);
0540   }
0541 
0542   NCollection_ForwardRangeSentinel end() const { return NCollection_ForwardRangeSentinel{}; }
0543 
0544 private:
0545   void advance()
0546   {
0547     myHasCurrent = false;
0548     while (myIndex < static_cast<uint32_t>(myRefs->Size()))
0549     {
0550       const RefIdType aRefId = myRefs->Value(static_cast<size_t>(myIndex));
0551       if (aRefId.IsValid(myNbRefs) && !aRefId.IsRemoved(*myGraph))
0552       {
0553         const IdType anId = TraitsT::Id(*myGraph, aRefId);
0554         if (anId.IsValid(myNbIds) && !anId.IsRemoved(*myGraph))
0555         {
0556           myCurrent    = anId;
0557           myCurrentRef = aRefId;
0558           myHasCurrent = true;
0559           return;
0560         }
0561       }
0562       ++myIndex;
0563     }
0564   }
0565 
0566   const BRepGraph*     myGraph = nullptr;
0567   const ContainerType* myRefs  = nullptr;
0568   IdType               myCurrent;
0569   RefIdType            myCurrentRef;
0570   uint32_t             myNbRefs     = 0;
0571   uint32_t             myNbIds      = 0;
0572   uint32_t             myIndex      = 0;
0573   bool                 myHasCurrent = false;
0574 };
0575 
0576 struct WireOfCoEdgeUsageTraits
0577 {
0578   using ParentId      = BRepGraph_WireId;
0579   using ChildId       = BRepGraph_CoEdgeId;
0580   using RefId         = BRepGraph_CoEdgeId;
0581   using ContainerType = NCollection_LinearVector<ParentId>;
0582 
0583   static RefId FindRef(const BRepGraph&         theGraph,
0584                        const BRepGraph_WireId   theParent,
0585                        const BRepGraph_CoEdgeId theChild)
0586   {
0587     for (BRepGraph_CoEdgesOfWire aIt(theGraph, theParent); aIt.More(); aIt.Next())
0588     {
0589       if (aIt.CurrentId() == theChild)
0590       {
0591         return aIt.CurrentId();
0592       }
0593     }
0594     return RefId();
0595   }
0596 };
0597 
0598 struct WireFromEdgeCoEdgeTraits
0599 {
0600   using ParentId = BRepGraph_WireId;
0601 
0602   static ParentId ParentIdOf(const BRepGraphInc::CoEdgeDef& theCoEdge)
0603   {
0604     return theCoEdge.ParentWireId;
0605   }
0606 
0607   static uint32_t NbParents(const BRepGraph& theGraph) { return theGraph.Topo().Wires().Nb(); }
0608 };
0609 
0610 struct FaceFromEdgeCoEdgeTraits
0611 {
0612   using ParentId = BRepGraph_FaceId;
0613 
0614   static ParentId ParentIdOf(const BRepGraphInc::CoEdgeDef& theCoEdge) { return theCoEdge.FaceId; }
0615 
0616   static uint32_t NbParents(const BRepGraph& theGraph) { return theGraph.Topo().Faces().Nb(); }
0617 };
0618 
0619 struct EdgeOfVertexRefTraits
0620 {
0621   using ParentId      = BRepGraph_EdgeId;
0622   using ChildId       = BRepGraph_VertexId;
0623   using RefId         = BRepGraph_VertexRefId;
0624   using ContainerType = NCollection_LinearVector<ParentId>;
0625 
0626   static RefId FindRef(const BRepGraph&         theGraph,
0627                        const BRepGraph_EdgeId   theParent,
0628                        const BRepGraph_VertexId theChild)
0629   {
0630     for (BRepGraph_RefsVertexOfEdge aIt(theGraph, theParent); aIt.More(); aIt.Next())
0631     {
0632       if (theGraph.Refs().Gen().ChildNode(aIt.CurrentId()) == BRepGraph_NodeId(theChild))
0633       {
0634         return aIt.CurrentId();
0635       }
0636     }
0637     return RefId();
0638   }
0639 };
0640 
0641 struct FaceFromWireRefTraits
0642 {
0643   using IdType        = BRepGraph_FaceId;
0644   using RefIdType     = BRepGraph_WireRefId;
0645   using ContainerType = NCollection_LinearVector<RefIdType>;
0646 
0647   static IdType Id(const BRepGraph& theGraph, const RefIdType theRefId)
0648   {
0649     return theGraph.Refs().Wires().Entry(theRefId).ParentFaceId;
0650   }
0651 };
0652 
0653 struct ShellFromFaceRefTraits
0654 {
0655   using IdType        = BRepGraph_ShellId;
0656   using RefIdType     = BRepGraph_FaceRefId;
0657   using ContainerType = NCollection_LinearVector<RefIdType>;
0658 
0659   static IdType Id(const BRepGraph& theGraph, const RefIdType theRefId)
0660   {
0661     return theGraph.Refs().Faces().Entry(theRefId).ParentShellId;
0662   }
0663 };
0664 
0665 struct SolidFromShellRefTraits
0666 {
0667   using IdType        = BRepGraph_SolidId;
0668   using RefIdType     = BRepGraph_ShellRefId;
0669   using ContainerType = NCollection_LinearVector<RefIdType>;
0670 
0671   static IdType Id(const BRepGraph& theGraph, const RefIdType theRefId)
0672   {
0673     return theGraph.Refs().Shells().Entry(theRefId).ParentSolidId;
0674   }
0675 };
0676 
0677 struct CompSolidFromSolidRefTraits
0678 {
0679   using IdType        = BRepGraph_CompSolidId;
0680   using RefIdType     = BRepGraph_SolidRefId;
0681   using ContainerType = NCollection_LinearVector<RefIdType>;
0682 
0683   static IdType Id(const BRepGraph& theGraph, const RefIdType theRefId)
0684   {
0685     return theGraph.Refs().Solids().Entry(theRefId).ParentCompSolidId;
0686   }
0687 };
0688 
0689 struct CompoundFromChildRefTraits
0690 {
0691   using IdType        = BRepGraph_CompoundId;
0692   using RefIdType     = BRepGraph_ChildRefId;
0693   using ContainerType = NCollection_LinearVector<RefIdType>;
0694 
0695   static IdType Id(const BRepGraph& theGraph, const RefIdType theRefId)
0696   {
0697     return theGraph.Refs().Children().Entry(theRefId).ParentCompoundId;
0698   }
0699 };
0700 
0701 struct OccurrenceFromOccurrenceRefTraits
0702 {
0703   using IdType        = BRepGraph_OccurrenceId;
0704   using RefIdType     = BRepGraph_OccurrenceRefId;
0705   using ContainerType = NCollection_LinearVector<RefIdType>;
0706 
0707   static IdType Id(const BRepGraph& theGraph, const RefIdType theRefId)
0708   {
0709     return theGraph.Refs().Occurrences().Entry(theRefId).ChildOccurrenceId;
0710   }
0711 };
0712 
0713 struct ProductFromOccurrenceRefTraits
0714 {
0715   using IdType        = BRepGraph_ProductId;
0716   using RefIdType     = BRepGraph_OccurrenceRefId;
0717   using ContainerType = NCollection_LinearVector<RefIdType>;
0718 
0719   static IdType Id(const BRepGraph& theGraph, const RefIdType theRefId)
0720   {
0721     return theGraph.Refs().Occurrences().Entry(theRefId).ParentProductId;
0722   }
0723 };
0724 
0725 } // namespace BRepGraph_ReverseIterator
0726 
0727 // Vertex -> parent Edges
0728 using BRepGraph_EdgesOfVertex =
0729   BRepGraph_ReverseIterator::ParentsOf<BRepGraph_EdgeId,
0730                                        NCollection_LinearVector<BRepGraph_EdgeId>>;
0731 // Vertex -> parent Compounds
0732 using BRepGraph_CompoundsOfVertex =
0733   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0734 
0735 // Edge -> parent Wires
0736 class BRepGraph_WiresOfEdge : public BRepGraph_ReverseIterator::EdgeParentsOf<
0737                                 BRepGraph_ReverseIterator::WireFromEdgeCoEdgeTraits>
0738 {
0739 public:
0740   using BRepGraph_ReverseIterator::EdgeParentsOf<
0741     BRepGraph_ReverseIterator::WireFromEdgeCoEdgeTraits>::EdgeParentsOf;
0742 };
0743 
0744 // Edge -> parent CoEdges
0745 using BRepGraph_CoEdgesOfEdge =
0746   BRepGraph_ReverseIterator::ParentsOf<BRepGraph_CoEdgeId,
0747                                        NCollection_LinearVector<BRepGraph_CoEdgeId>>;
0748 
0749 // Edge -> parent Faces (derived from CoEdge.FaceId)
0750 class BRepGraph_FacesOfEdge : public BRepGraph_ReverseIterator::EdgeParentsOf<
0751                                 BRepGraph_ReverseIterator::FaceFromEdgeCoEdgeTraits>
0752 {
0753 public:
0754   using BRepGraph_ReverseIterator::EdgeParentsOf<
0755     BRepGraph_ReverseIterator::FaceFromEdgeCoEdgeTraits>::EdgeParentsOf;
0756 };
0757 
0758 // Edge -> parent Compounds
0759 using BRepGraph_CompoundsOfEdge =
0760   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0761 // CoEdge -> parent Compounds
0762 using BRepGraph_CompoundsOfCoEdge =
0763   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0764 // Wire -> parent Faces
0765 using BRepGraph_FacesOfWire =
0766   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::FaceFromWireRefTraits>;
0767 // Wire -> parent Compounds
0768 using BRepGraph_CompoundsOfWire =
0769   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0770 // Face -> parent Shells
0771 using BRepGraph_ShellsOfFace =
0772   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::ShellFromFaceRefTraits>;
0773 // Face -> parent Compounds
0774 using BRepGraph_CompoundsOfFace =
0775   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0776 // Shell -> parent Solids
0777 using BRepGraph_SolidsOfShell =
0778   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::SolidFromShellRefTraits>;
0779 // Shell -> parent Compounds
0780 using BRepGraph_CompoundsOfShell =
0781   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0782 // Solid -> parent CompSolids
0783 using BRepGraph_CompSolidsOfSolid =
0784   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompSolidFromSolidRefTraits>;
0785 // Solid -> parent Compounds
0786 using BRepGraph_CompoundsOfSolid =
0787   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0788 // CompSolid -> parent Compounds
0789 using BRepGraph_CompoundsOfCompSolid =
0790   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0791 // Compound -> parent Compounds
0792 using BRepGraph_CompoundsOfCompound =
0793   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0794 // Any child -> parent Compounds
0795 using BRepGraph_CompoundsOfChild =
0796   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0797 // Product -> Occurrences
0798 using BRepGraph_OccurrencesOfProduct = BRepGraph_ReverseIterator::IdsOfRefs<
0799   BRepGraph_ReverseIterator::OccurrenceFromOccurrenceRefTraits>;
0800 // Any occurrence child -> Occurrences
0801 using BRepGraph_OccurrencesOfChild = BRepGraph_ReverseIterator::IdsOfRefs<
0802   BRepGraph_ReverseIterator::OccurrenceFromOccurrenceRefTraits>;
0803 // Occurrence -> parent Products
0804 using BRepGraph_ProductsOfOccurrence =
0805   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::ProductFromOccurrenceRefTraits>;
0806 
0807 // Ref-based reverse iterators: yield (ParentId, RefId) pairs.
0808 // These find the specific reference entry in each parent that links to the child.
0809 
0810 // Wire -> parent Faces (with WireRefId)
0811 using BRepGraph_RefsFacesOfWire =
0812   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::FaceFromWireRefTraits>;
0813 // Face -> parent Shells (with FaceRefId)
0814 using BRepGraph_RefsShellsOfFace =
0815   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::ShellFromFaceRefTraits>;
0816 // Shell -> parent Solids (with ShellRefId)
0817 using BRepGraph_RefsSolidsOfShell =
0818   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::SolidFromShellRefTraits>;
0819 // CoEdge -> parent Wires (with direct CoEdgeId usage in each wire)
0820 using BRepGraph_RefsWiresOfCoEdge =
0821   BRepGraph_ReverseIterator::LookupParentRefsOf<BRepGraph_ReverseIterator::WireOfCoEdgeUsageTraits>;
0822 // Vertex -> parent Edges (with VertexRefId)
0823 using BRepGraph_RefsEdgesOfVertex =
0824   BRepGraph_ReverseIterator::LookupParentRefsOf<BRepGraph_ReverseIterator::EdgeOfVertexRefTraits>;
0825 // Solid -> parent CompSolids (with SolidRefId)
0826 using BRepGraph_RefsCompSolidsOfSolid =
0827   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompSolidFromSolidRefTraits>;
0828 // Any child -> parent Compounds (with ChildRefId)
0829 using BRepGraph_RefsCompoundsOfChild =
0830   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::CompoundFromChildRefTraits>;
0831 // Occurrence -> parent Products (with OccurrenceRefId)
0832 using BRepGraph_RefsProductsOfOccurrence =
0833   BRepGraph_ReverseIterator::IdsOfRefs<BRepGraph_ReverseIterator::ProductFromOccurrenceRefTraits>;
0834 
0835 #endif // _BRepGraph_ReverseIterator_HeaderFile