// Copyright (c) 2026 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _BRepGraph_Iterator_HeaderFile #define _BRepGraph_Iterator_HeaderFile #include "BRepGraph.hxx" #include "BRepGraph_TopoView.hxx" #include "NCollection_ForwardRange.hxx" #include //! @brief Type-safe, allocation-free iterator over BRepGraph definition nodes. //! @see BRepGraph class comment "Iterator guide" for choosing between iterator types. //! //! Provides sequential read-only access to definitions stored in BRepGraph. //! By default nodes with IsRemoved flag are skipped; set TheFullTraverse //! to true to include them (types without IsRemoved are unaffected). //! //! ## Usage //! @code //! for (BRepGraph_Iterator anIt(aGraph); //! anIt.More(); anIt.Next()) //! { //! const BRepGraphInc::FaceDef& aFace = anIt.Current(); //! } //! @endcode namespace BRepGraph_IteratorDetail { //! Compile-time traits mapping from definition type to typed NodeId, //! count accessor, and definition accessor. template struct NodeTraits; template <> struct NodeTraits { using TypedId = BRepGraph_SolidId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().Solids().Nb(); } static const BRepGraphInc::SolidDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().Solids().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_ShellId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().Shells().Nb(); } static const BRepGraphInc::ShellDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().Shells().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_FaceId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().Faces().Nb(); } static const BRepGraphInc::FaceDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().Faces().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_WireId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().Wires().Nb(); } static const BRepGraphInc::WireDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().Wires().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_EdgeId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().Edges().Nb(); } static const BRepGraphInc::EdgeDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().Edges().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_VertexId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().Vertices().Nb(); } static const BRepGraphInc::VertexDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().Vertices().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_ProductId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().Products().Nb(); } static const BRepGraphInc::ProductDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().Products().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_OccurrenceId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().Occurrences().Nb(); } static const BRepGraphInc::OccurrenceDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().Occurrences().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_CoEdgeId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().CoEdges().Nb(); } static const BRepGraphInc::CoEdgeDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().CoEdges().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_CompoundId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().Compounds().Nb(); } static const BRepGraphInc::CompoundDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().Compounds().Definition(theId); } }; template <> struct NodeTraits { using TypedId = BRepGraph_CompSolidId; static uint32_t Count(const BRepGraph& theGraph) { return theGraph.Topo().CompSolids().Nb(); } static const BRepGraphInc::CompSolidDef& Get(const BRepGraph& theGraph, const TypedId theId) { return theGraph.Topo().CompSolids().Definition(theId); } }; } // namespace BRepGraph_IteratorDetail //! @brief Type-safe, allocation-free iterator over BRepGraph definition nodes. //! //! @tparam NodeType Definition struct type (e.g. BRepGraphInc::FaceDef). //! @tparam TheFullTraverse When true, removed nodes are NOT skipped (for special cases). template class BRepGraph_Iterator { public: using Traits = BRepGraph_IteratorDetail::NodeTraits; using TypedId = typename Traits::TypedId; BRepGraph_Iterator(const BRepGraph& theGraph) : myGraph(theGraph), myLength(TypedId(Traits::Count(theGraph))) { skipRemoved(); } BRepGraph_Iterator(const BRepGraph& theGraph, const TypedId theStartId) : myGraph(theGraph), myCurrent(theStartId), myLength(TypedId(Traits::Count(theGraph))) { if (myCurrent < TypedId::Start()) { myCurrent = TypedId::Start(); } skipRemoved(); } [[nodiscard]] bool More() const { return myCurrent < myLength; } void Next() { ++myCurrent; skipRemoved(); } [[nodiscard]] const NodeType& Current() const { return Traits::Get(myGraph, myCurrent); } //! Current definition index as a typed NodeId. [[nodiscard]] TypedId CurrentId() const { return myCurrent; } //! Returns an STL-compatible iterator for range-based for loops. NCollection_ForwardRangeIterator begin() { return NCollection_ForwardRangeIterator(this); } //! Returns a sentinel marking the end of iteration. NCollection_ForwardRangeSentinel end() const { return NCollection_ForwardRangeSentinel{}; } private: //! Advance past any nodes marked as removed. void skipRemoved() { if constexpr (!TheFullTraverse) { while (myCurrent < myLength && myCurrent.IsRemoved(myGraph)) { ++myCurrent; } } } const BRepGraph& myGraph; TypedId myCurrent = TypedId::Start(); TypedId myLength; }; // --------------------------------------------------------------------------- // Convenience type aliases (skip removed nodes default) // --------------------------------------------------------------------------- using BRepGraph_SolidIterator = BRepGraph_Iterator; using BRepGraph_ShellIterator = BRepGraph_Iterator; using BRepGraph_FaceIterator = BRepGraph_Iterator; using BRepGraph_WireIterator = BRepGraph_Iterator; using BRepGraph_EdgeIterator = BRepGraph_Iterator; using BRepGraph_VertexIterator = BRepGraph_Iterator; using BRepGraph_CoEdgeIterator = BRepGraph_Iterator; using BRepGraph_CompoundIterator = BRepGraph_Iterator; using BRepGraph_CompSolidIterator = BRepGraph_Iterator; using BRepGraph_ProductIterator = BRepGraph_Iterator; using BRepGraph_OccurrenceIterator = BRepGraph_Iterator; // --------------------------------------------------------------------------- // Full-traverse aliases (include removed/invalidated nodes use only // in special cases such as compaction, validation, or debugging) // --------------------------------------------------------------------------- using BRepGraph_FullSolidIterator = BRepGraph_Iterator; using BRepGraph_FullShellIterator = BRepGraph_Iterator; using BRepGraph_FullFaceIterator = BRepGraph_Iterator; using BRepGraph_FullWireIterator = BRepGraph_Iterator; using BRepGraph_FullEdgeIterator = BRepGraph_Iterator; using BRepGraph_FullVertexIterator = BRepGraph_Iterator; using BRepGraph_FullCoEdgeIterator = BRepGraph_Iterator; using BRepGraph_FullCompoundIterator = BRepGraph_Iterator; using BRepGraph_FullCompSolidIterator = BRepGraph_Iterator; using BRepGraph_FullProductIterator = BRepGraph_Iterator; using BRepGraph_FullOccurrenceIterator = BRepGraph_Iterator; //! @brief Allocation-free iterator over root product identifiers. //! //! Iterates directly over BRepGraph::RootProductIds() - products not //! referenced by any active occurrence. class BRepGraph_RootProductIterator { public: explicit BRepGraph_RootProductIterator(const BRepGraph& theGraph) : myRoots(theGraph.RootProductIds()) { } [[nodiscard]] bool More() const { return myIndex < myRoots.Size(); } void Next() { ++myIndex; } [[nodiscard]] const BRepGraph_ProductId& Current() const { return myRoots.Value(myIndex); } NCollection_ForwardRangeIterator begin() { return NCollection_ForwardRangeIterator(this); } NCollection_ForwardRangeSentinel end() const { return NCollection_ForwardRangeSentinel{}; } private: const NCollection_LinearVector& myRoots; size_t myIndex = 0; }; #endif // _BRepGraph_Iterator_HeaderFile