Back to home page

EIC code displayed by LXR

 
 

    


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

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_Layer_HeaderFile
0015 #define _BRepGraph_Layer_HeaderFile
0016 
0017 #include <BRepGraph.hxx>
0018 #include <BRepGraph_CopyRemap.hxx>
0019 #include <BRepGraph_ItemId.hxx>
0020 #include <BRepGraph_NodeId.hxx>
0021 #include <BRepGraph_RefId.hxx>
0022 #include <NCollection_Array1.hxx>
0023 #include <NCollection_DataMap.hxx>
0024 #include <NCollection_FlatDataMap.hxx>
0025 #include <Standard_GUID.hxx>
0026 #include <Standard_Transient.hxx>
0027 #include <TCollection_AsciiString.hxx>
0028 
0029 #include <cstdint>
0030 #include <memory>
0031 
0032 class BRepGraph_LayerRegistry;
0033 
0034 //! @brief Abstract base class for named attribute layers.
0035 //!
0036 //! A layer groups per-node and per-reference metadata under a unique name with
0037 //! lifecycle callbacks. Layers are registered on BRepGraph and automatically
0038 //! notified when nodes or references are removed, remapped (compact), or modified.
0039 //!
0040 //! Derived layers store domain-specific data (names, colors, materials, etc.)
0041 //! in internal maps keyed by BRepGraph_NodeId or BRepGraph_RefId. The lifecycle
0042 //! callbacks ensure data consistency across all graph mutations.
0043 //!
0044 //! ## Node Modification Events
0045 //! Layers subscribe to node modification events by overriding SubscribedKinds()
0046 //! to return a non-zero bitmask of Kind values. When a subscribed node kind is
0047 //! modified, OnNodeModified() (immediate mode) or OnNodesModified() (deferred
0048 //! batch mode) is called. Layers with SubscribedKinds() == 0 (default) incur
0049 //! zero dispatch overhead.
0050 //!
0051 //! ## Reference Modification Events
0052 //! Layers subscribe to reference modification events by overriding
0053 //! SubscribedRefKinds() to return a non-zero bitmask of BRepGraph_RefId::Kind
0054 //! values. When a subscribed ref kind is mutated, OnRefModified() (immediate
0055 //! mode) or OnRefsModified() (deferred batch mode) is called. Removal is always
0056 //! dispatched via OnRefRemoved() regardless of subscription.
0057 //!
0058 //! ## Thread safety
0059 //! Callback dispatch is single-threaded (called from mutation paths).
0060 //! Layers that only provide read access can skip internal locking.
0061 //!
0062 //! @warning All lifecycle callbacks are declared noexcept. Derived
0063 //! implementations that throw will cause std::terminate. This is enforced
0064 //! by C++ language semantics for noexcept virtual overrides.
0065 class BRepGraph_Layer : public Standard_Transient
0066 {
0067 public:
0068   //! Layer type identity (unique within a graph).
0069   [[nodiscard]] virtual const Standard_GUID& ID() const = 0;
0070 
0071   //! Layer identity (unique within a graph).
0072   [[nodiscard]] virtual const TCollection_AsciiString& Name() const = 0;
0073 
0074   //! Called when a node is soft-removed without a replacement.
0075   //! @param[in] theNode the removed node
0076   //!            Layers should discard or archive data associated with it.
0077   //! @warning Layer callbacks must not throw. They are called from noexcept
0078   //! notification paths (MutGuard destructors, deferred invalidation flush).
0079   Standard_EXPORT virtual void OnNodeRemoved(const BRepGraph_NodeId theNode) noexcept;
0080 
0081   //! Dispatch a generic item removal to the matching typed removal callback.
0082   //! This is a non-virtual convenience entry point; typed callbacks remain the
0083   //! extension points for derived layers.
0084   //! @param[in] theItem the removed definition or reference
0085   Standard_EXPORT void OnItemRemoved(const BRepGraph_ItemId theItem) noexcept;
0086 
0087   //! Called when a node is soft-removed and replaced by another node.
0088   //! @param[in] theOldNode the removed node
0089   //! @param[in] theNewNode the node that replaces theOldNode
0090   //!            Layers that store node-keyed data should migrate from
0091   //!            theOldNode to theNewNode when the replacement kind is
0092   //!            compatible. This is a structural lifecycle event, not an
0093   //!            algorithmic history record.
0094   //! @warning Layer callbacks must not throw. They are called from noexcept
0095   //! notification paths (MutGuard destructors, deferred invalidation flush).
0096   Standard_EXPORT virtual void OnNodeReplaced(const BRepGraph_NodeId theOldNode,
0097                                               const BRepGraph_NodeId theNewNode) noexcept;
0098 
0099   //! Copy this source layer data into another graph.
0100   //! The source graph is the graph this layer is attached to (Graph()).
0101   //! @param[in] theCopy source graph, target graph, and source item id -> target item id remap
0102   //! @note Missing source items were not copied; persistent layers should skip dependent records.
0103   //! @note For BRepGraph_CopyRemap::Mode::Compact, the layer is being migrated in-place after
0104   //! structural compaction. UID/ItemUID records and ref/rep entries should be remapped through
0105   //! the item map. Stale entries (absent from the remap) should be dropped.
0106   //! @warning This callback may allocate and is intentionally not noexcept.
0107   Standard_EXPORT virtual void CopyTo(const BRepGraph_CopyRemap& theCopy) const = 0;
0108 
0109   //! Mark all cached values dirty (bulk invalidation).
0110   virtual void InvalidateAll() noexcept = 0;
0111 
0112   //! Clear all stored data.
0113   virtual void Clear() noexcept = 0;
0114 
0115   //! Return a bitmask of BRepGraph_NodeId::Kind values this layer subscribes to.
0116   //! Only modification events matching subscribed kinds are dispatched.
0117   //! Default: 0 (no subscription - no modification events received).
0118   //! Override to receive OnNodeModified/OnNodesModified callbacks.
0119   //! The returned value must be constant for the lifetime of the layer.
0120   [[nodiscard]] Standard_EXPORT virtual int SubscribedKinds() const;
0121 
0122   //! Called in immediate (non-deferred) mode after a single node is modified.
0123   //! Only dispatched if the node's kind matches SubscribedKinds().
0124   //! Default: no-op.
0125   //! @param[in] theNode the modified node
0126   Standard_EXPORT virtual void OnNodeModified(const BRepGraph_NodeId theNode) noexcept;
0127 
0128   //! Dispatch a generic item modification to the matching typed modification callback.
0129   //! This is a non-virtual convenience entry point; typed callbacks remain the
0130   //! extension points for derived layers.
0131   //! @param[in] theItem the modified definition or reference
0132   Standard_EXPORT void OnItemModified(const BRepGraph_ItemId theItem) noexcept;
0133 
0134   //! Called after EndDeferredInvalidation() with all nodes modified during
0135   //! the deferred scope. Only dispatched if at least one modified node's kind
0136   //! matches SubscribedKinds(). The array may contain nodes of kinds not
0137   //! subscribed to - layers should filter internally if needed.
0138   //! Default: no-op.
0139   //! @param[in] theModifiedNodes all modified, non-removed nodes
0140   Standard_EXPORT virtual void OnNodesModified(
0141     const NCollection_Array1<BRepGraph_NodeId>& theModifiedNodes) noexcept;
0142 
0143   //! Convenience: return bitmask bit for a given Kind.
0144   static int KindBit(const BRepGraph_NodeId::Kind theKind)
0145   {
0146     return 1 << static_cast<int>(theKind);
0147   }
0148 
0149   //! Return a bitmask of BRepGraph_RefId::Kind values this layer subscribes to.
0150   //! Only modification events matching subscribed ref kinds are dispatched.
0151   //! Default: 0 (no subscription). Must be constant for the layer's lifetime.
0152   [[nodiscard]] Standard_EXPORT virtual int SubscribedRefKinds() const;
0153 
0154   //! Called when a reference is soft-deleted via RemoveRef().
0155   //! No replacement concept - refs are simply removed (unlike nodes which can have
0156   //! a replacement during sewing or deduplication). Dispatched to all layers
0157   //! regardless of SubscribedRefKinds().
0158   //! Default: no-op.
0159   //! @param[in] theRef the removed reference
0160   Standard_EXPORT virtual void OnRefRemoved(const BRepGraph_RefId theRef) noexcept;
0161 
0162   //! Called in immediate (non-deferred) mode after a single ref is mutated.
0163   //! Only dispatched if the ref's kind matches SubscribedRefKinds().
0164   //! Default: no-op.
0165   //! @param[in] theRef the modified reference
0166   Standard_EXPORT virtual void OnRefModified(const BRepGraph_RefId theRef) noexcept;
0167 
0168   //! Called after EndDeferredInvalidation() with all refs modified during
0169   //! the deferred scope. Only dispatched if at least one modified ref's kind
0170   //! matches SubscribedRefKinds(). The array may contain refs of kinds not
0171   //! subscribed to - layers should filter internally if needed.
0172   //! Default: no-op.
0173   //! @param[in] theModifiedRefs all modified, non-removed refs
0174   Standard_EXPORT virtual void OnRefsModified(
0175     const NCollection_Array1<BRepGraph_RefId>& theModifiedRefs) noexcept;
0176 
0177   //! Convenience: return bitmask bit for a given RefId::Kind.
0178   static int RefKindBit(const BRepGraph_RefId::Kind theKind)
0179   {
0180     return 1 << static_cast<int>(theKind);
0181   }
0182 
0183   //! Monotonic revision counter incremented by touch() on every observable
0184   //! state change. Consumers compare stored revisions to detect staleness in O(1).
0185   //! Derived layers MUST call touch() from their mutators.
0186   [[nodiscard]] uint64_t Revision() const noexcept { return myRevision; }
0187 
0188 protected:
0189   Standard_EXPORT BRepGraph_Layer();
0190 
0191   //! Bump the revision counter.
0192   void touch() noexcept { ++myRevision; }
0193 
0194   //! True while this layer is registered in a live graph registry.
0195   [[nodiscard]] bool IsAttached() const noexcept { return myGraph != nullptr; }
0196 
0197   //! Attached graph for read-only layer services. Raises Standard_ProgramError if detached.
0198   [[nodiscard]] Standard_EXPORT const BRepGraph& Graph() const;
0199 
0200   //! Attached mutable graph for graph-owned service layers. Returns null if detached.
0201   [[nodiscard]] BRepGraph* AttachedGraph() const noexcept { return myGraph; }
0202 
0203   template <BRepGraph_NodeId::Kind TheKind>
0204   [[nodiscard]] static BRepGraph_NodeId::Typed<TheKind> RemappedItem(
0205     const BRepGraph_CopyRemap&             theCopy,
0206     const BRepGraph_NodeId::Typed<TheKind> theId)
0207   {
0208     if (!theId.IsValid())
0209     {
0210       return BRepGraph_NodeId::Typed<TheKind>();
0211     }
0212     const BRepGraph_ItemId aMapped = theCopy.TargetItem(BRepGraph_ItemId(theId));
0213     if (!aMapped.IsNode())
0214     {
0215       return BRepGraph_NodeId::Typed<TheKind>();
0216     }
0217     return BRepGraph_NodeId::Typed<TheKind>::FromNodeId(aMapped.NodeId());
0218   }
0219 
0220   template <BRepGraph_RefId::Kind TheKind>
0221   [[nodiscard]] static BRepGraph_RefId::Typed<TheKind> RemappedItem(
0222     const BRepGraph_CopyRemap&            theCopy,
0223     const BRepGraph_RefId::Typed<TheKind> theId)
0224   {
0225     if (!theId.IsValid())
0226     {
0227       return BRepGraph_RefId::Typed<TheKind>();
0228     }
0229     const BRepGraph_ItemId aMapped = theCopy.TargetItem(BRepGraph_ItemId(theId));
0230     if (!aMapped.IsReference())
0231     {
0232       return BRepGraph_RefId::Typed<TheKind>();
0233     }
0234     return BRepGraph_RefId::Typed<TheKind>::FromRefId(aMapped.RefId());
0235   }
0236 
0237   //! Called after the layer is attached to a graph registry.
0238   Standard_EXPORT virtual void OnAttached() noexcept;
0239 
0240   //! Called before the layer is detached from a graph registry.
0241   Standard_EXPORT virtual void OnDetached() noexcept;
0242 
0243 private:
0244   friend class ::BRepGraph_LayerRegistry;
0245 
0246   Standard_EXPORT void attachGraph(BRepGraph* theGraph) noexcept;
0247   Standard_EXPORT void detachContext() noexcept;
0248 
0249   BRepGraph* myGraph    = nullptr;
0250   uint64_t   myRevision = 0;
0251 
0252 public:
0253   DEFINE_STANDARD_RTTIEXT(BRepGraph_Layer, Standard_Transient)
0254 };
0255 
0256 #endif // _BRepGraph_Layer_HeaderFile