Back to home page

EIC code displayed by LXR

 
 

    


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

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_RelatedIterator_HeaderFile
0015 #define _BRepGraph_RelatedIterator_HeaderFile
0016 
0017 #include <BRepGraph.hxx>
0018 #include <BRepGraph_DefsIterator.hxx>
0019 #include <BRepGraph_RefsIterator.hxx>
0020 #include <BRepGraph_ReverseIterator.hxx>
0021 #include <BRepGraph_RefsView.hxx>
0022 #include <BRepGraph_Tool.hxx>
0023 #include <BRepGraph_TopoView.hxx>
0024 #include <NCollection_ForwardRange.hxx>
0025 #include <NCollection_LinearVector.hxx>
0026 
0027 //! @brief Single-level iterator over semantically related topology nodes.
0028 //! @see BRepGraph class comment "Iterator guide" for choosing between iterator types.
0029 //!
0030 //! The iterator yields immediate related nodes for one source node together
0031 //! with the relation kind explaining why each node is returned. Results are not
0032 //! deduplicated; callers that need uniqueness should filter on top.
0033 class BRepGraph_RelatedIterator
0034 {
0035 public:
0036   //! Topological relation kinds yielded by the iterator.
0037   //! Only geometry-level relations are supported (Face, Edge, Vertex, Wire, CoEdge).
0038   //! Assembly/container nodes (Solid, Shell, Compound, Product, Occurrence) have
0039   //! no topological relations - use BRepGraph_ChildExplorer / BRepGraph_ParentExplorer instead.
0040   enum class RelationKind
0041   {
0042     BoundaryEdge,     //!< Face -> Edge bounding the face
0043     AdjacentFace,     //!< Face -> Face sharing an edge
0044     OuterWire,        //!< Face -> Wire (outer boundary)
0045     ReferencedByFace, //!< Edge -> Face that uses this edge
0046     IncidentVertex,   //!< Edge -> Vertex (start/end)
0047     WireCoEdge,       //!< Wire -> CoEdge (member)
0048     OwningFace,       //!< Wire/CoEdge -> Face (container)
0049     IncidentEdge,     //!< Vertex -> Edge (touching)
0050     ParentEdge,       //!< CoEdge -> Edge (underlying definition)
0051     SeamPair,         //!< CoEdge -> CoEdge (seam twin)
0052   };
0053 
0054   //! Internal traversal stage tracking which sub-iteration is active.
0055   enum class Stage
0056   {
0057     First,    //!< Primary relation iteration.
0058     Second,   //!< Secondary relation iteration.
0059     Third,    //!< Tertiary relation iteration.
0060     Finished, //!< All relations exhausted.
0061   };
0062 
0063   //! Construct an iterator over all semantically related nodes of the given source node.
0064   //! @param[in] theGraph graph containing the node
0065   //! @param[in] theNode  source node whose relations are iterated
0066   BRepGraph_RelatedIterator(const BRepGraph& theGraph, const BRepGraph_NodeId theNode)
0067       : myGraph(&theGraph),
0068         myNode(theNode)
0069   {
0070     advance();
0071   }
0072 
0073   //! True if another related node is available.
0074   [[nodiscard]] bool More() const { return myHasCurrent; }
0075 
0076   //! Advance to the next related node.
0077   void Next()
0078   {
0079     if (!myHasCurrent)
0080     {
0081       return;
0082     }
0083     advance();
0084   }
0085 
0086   //! Return the current related node id.
0087   [[nodiscard]] const BRepGraph_NodeId& Current() const { return myCurrent; }
0088 
0089   //! Return the relation kind explaining why the current node is related.
0090   [[nodiscard]] RelationKind CurrentRelation() const { return myRelation; }
0091 
0092   //! Returns an STL-compatible iterator for range-based for loops.
0093   NCollection_ForwardRangeIterator<BRepGraph_RelatedIterator> begin()
0094   {
0095     return NCollection_ForwardRangeIterator<BRepGraph_RelatedIterator>(this);
0096   }
0097 
0098   //! Returns a sentinel marking the end of iteration.
0099   NCollection_ForwardRangeSentinel end() const { return NCollection_ForwardRangeSentinel{}; }
0100 
0101 private:
0102   [[nodiscard]] bool setCurrent(const BRepGraph_NodeId theNode, const RelationKind theRelation);
0103 
0104   template <class IteratorT>
0105   [[nodiscard]] bool advanceRefChildren(IteratorT theIterator, const RelationKind theRelation)
0106   {
0107     for (; theIterator.More(); theIterator.Next())
0108     {
0109       if (theIterator.Index() < myIndex)
0110       {
0111         continue;
0112       }
0113 
0114       myIndex = theIterator.Index() + 1;
0115       BRepGraph_NodeId aChildNode;
0116       if constexpr (std::is_convertible_v<decltype(theIterator.CurrentId()), BRepGraph_RefId>)
0117       {
0118         aChildNode = myGraph->Refs().Gen().ChildNode(theIterator.CurrentId());
0119       }
0120       else
0121       {
0122         aChildNode = BRepGraph_NodeId(theIterator.CurrentId());
0123       }
0124       return setCurrent(aChildNode, theRelation);
0125     }
0126 
0127     return false;
0128   }
0129 
0130   template <class IteratorT>
0131   [[nodiscard]] bool advanceDefChildren(IteratorT theIterator, const RelationKind theRelation)
0132   {
0133     for (; theIterator.More(); theIterator.Next())
0134     {
0135       if (theIterator.Index() < myIndex)
0136       {
0137         continue;
0138       }
0139 
0140       myIndex = theIterator.Index() + 1;
0141       return setCurrent(BRepGraph_NodeId(theIterator.CurrentId()), theRelation);
0142     }
0143 
0144     return false;
0145   }
0146 
0147   [[nodiscard]] bool advanceFaceBoundaryEdge();
0148 
0149   [[nodiscard]] bool advanceAdjacentFace();
0150 
0151   [[nodiscard]] bool advanceEdgeVertex()
0152   {
0153     return advanceDefChildren(
0154       BRepGraph_DefsVertexOfEdge(*myGraph, BRepGraph_EdgeId::FromNodeId(myNode)),
0155       RelationKind::IncidentVertex);
0156   }
0157 
0158   //! Advance through a relation iterator (e.g. BRepGraph_FacesOfEdge).
0159   //! Constructs a ParentsOf starting at myIndex for O(1) amortized resumption.
0160   template <typename TypedIdT>
0161   [[nodiscard]] bool advanceParents(const NCollection_LinearVector<TypedIdT>& theParents,
0162                                     const RelationKind                        theRelation)
0163   {
0164     BRepGraph_ReverseIterator::ParentsOf<TypedIdT, NCollection_LinearVector<TypedIdT>> anIt(
0165       *myGraph,
0166       theParents,
0167       myIndex);
0168     if (anIt.More())
0169     {
0170       myIndex = anIt.Index() + 1;
0171       return setCurrent(BRepGraph_NodeId(anIt.CurrentId()), theRelation);
0172     }
0173 
0174     return false;
0175   }
0176 
0177   template <typename IteratorT>
0178   [[nodiscard]] bool advanceParentIterator(IteratorT theIterator, const RelationKind theRelation)
0179   {
0180     if (theIterator.More())
0181     {
0182       myIndex = theIterator.Index() + 1;
0183       return setCurrent(BRepGraph_NodeId(theIterator.CurrentId()), theRelation);
0184     }
0185     return false;
0186   }
0187 
0188   Standard_EXPORT void advance();
0189 
0190 private:
0191   const BRepGraph* myGraph;
0192   BRepGraph_NodeId myNode;
0193   BRepGraph_NodeId myCurrent;
0194   RelationKind     myRelation   = RelationKind::BoundaryEdge;
0195   Stage            myStage      = Stage::First;
0196   uint32_t         myIndex      = 0;
0197   uint32_t         myInnerIndex = 0;
0198   uint32_t         myDeepIndex  = 0;
0199   bool             myHasCurrent = false;
0200 };
0201 
0202 #endif // _BRepGraph_RelatedIterator_HeaderFile