Back to home page

EIC code displayed by LXR

 
 

    


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

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_CacheMesh_HeaderFile
0015 #define _BRepGraph_CacheMesh_HeaderFile
0016 
0017 #include <BRepGraph_Cache.hxx>
0018 #include <BRepGraph_NodeId.hxx>
0019 #include <Message_ProgressRange.hxx>
0020 #include <NCollection_Array1.hxx>
0021 #include <NCollection_DynamicArray.hxx>
0022 #include <NCollection_LinearVector.hxx>
0023 #include <Poly_Polygon2D.hxx>
0024 #include <Poly_Polygon3D.hxx>
0025 #include <Poly_PolygonOnTriangulation.hxx>
0026 #include <Poly_Triangulation.hxx>
0027 
0028 #include <cstdint>
0029 
0030 class BRepGraph;
0031 
0032 //! @brief Registry-owned runtime mesh cache for BRepGraph.
0033 //!
0034 //! CacheMesh stores transient triangulations and polygons produced by meshing drivers.
0035 //! It is not copied, transformed, or serialized. Persistent mesh representations remain
0036 //! in topology definitions and are filled only by import, authored primitive creation,
0037 //! or explicit promotion.
0038 class BRepGraph_CacheMesh : public BRepGraph_Cache
0039 {
0040 public:
0041   using SlotId = uint32_t;
0042 
0043   static constexpr SlotId DefaultDisplaySlot = 0;
0044 
0045   //! Entry stamp against the slot recipe and cache-local generation.
0046   struct EntryStamp
0047   {
0048     uint64_t RecipeHash     = 0;
0049     uint32_t SlotGeneration = 0;
0050 
0051     void Reset() noexcept
0052     {
0053       RecipeHash     = 0;
0054       SlotGeneration = 0;
0055     }
0056   };
0057 
0058   //! Cached mesh entry for a face: single triangulation.
0059   struct FaceMeshEntry : public NodeEntry
0060   {
0061     occ::handle<Poly_Triangulation> Triangulation;
0062     EntryStamp                      Stamp;
0063     uint32_t                        MeshGeneration = 0;
0064 
0065     [[nodiscard]] bool IsPresent() const { return !Triangulation.IsNull(); }
0066 
0067     //! Clear triangulation representation. Does NOT bump MeshGeneration -
0068     //! callers must call BRepGraph_CacheMesh::BumpFaceMeshGeneration() separately.
0069     void ClearRepresentation() noexcept { Triangulation.Nullify(); }
0070 
0071     void Reset() noexcept
0072     {
0073       NodeEntry::Reset();
0074       Triangulation.Nullify();
0075       Stamp.Reset();
0076       MeshGeneration = 0;
0077     }
0078   };
0079 
0080   //! Cached mesh entry for a coedge: polygon-in-parametric-space and polygon-on-triangulation.
0081   //!
0082   //! CoEdgeMeshEntry composes two NodeEntry fields instead of inheriting from one.
0083   //! This breaks the inheritance pattern used by other entries because the coedge
0084   //! has two independent freshness dimensions: coedge topology and face mesh content.
0085   struct CoEdgeMeshEntry
0086   {
0087     //! Coedge topology freshness (for Polygon2D).
0088     NodeEntry CoEdgeStamp;
0089 
0090     //! Face topology freshness (for PolygonsOnTri).
0091     NodeEntry FaceTopologyStamp;
0092 
0093     //! Face mesh content freshness (for PolygonsOnTri).
0094     uint32_t FaceMeshGeneration = 0;
0095     //! Face whose MeshGeneration we track.
0096     BRepGraph_FaceId BoundFaceId;
0097 
0098     //! Slot recipe freshness.
0099     EntryStamp SlotStamp;
0100 
0101     //! Cached polygon-on-surface.
0102     occ::handle<Poly_Polygon2D> Polygon2D;
0103     //! Cached polygons-on-triangulation.
0104     NCollection_LinearVector<occ::handle<Poly_PolygonOnTriangulation>> PolygonsOnTri;
0105 
0106     [[nodiscard]] bool IsPresent() const { return !Polygon2D.IsNull() || !PolygonsOnTri.IsEmpty(); }
0107 
0108     void Reset() noexcept
0109     {
0110       CoEdgeStamp.Reset();
0111       FaceTopologyStamp.Reset();
0112       FaceMeshGeneration = 0;
0113       BoundFaceId        = BRepGraph_FaceId();
0114       SlotStamp.Reset();
0115       Polygon2D.Nullify();
0116       PolygonsOnTri.Clear();
0117     }
0118   };
0119 
0120   //! Cached mesh entry for an edge: polygon-3D.
0121   struct EdgeMeshEntry : public NodeEntry
0122   {
0123     occ::handle<Poly_Polygon3D> Polygon3D;
0124     EntryStamp                  Stamp;
0125 
0126     [[nodiscard]] bool IsPresent() const { return !Polygon3D.IsNull(); }
0127 
0128     void Reset() noexcept
0129     {
0130       NodeEntry::Reset();
0131       Polygon3D.Nullify();
0132       Stamp.Reset();
0133     }
0134   };
0135 
0136   //! Dirty topology set requested from a cache driver.
0137   struct DirtySet
0138   {
0139     NCollection_LinearVector<BRepGraph_FaceId> Faces;
0140     NCollection_LinearVector<BRepGraph_EdgeId> FreeEdges;
0141 
0142     [[nodiscard]] bool IsEmpty() const { return Faces.IsEmpty() && FreeEdges.IsEmpty(); }
0143 
0144     void Clear()
0145     {
0146       Faces.Clear();
0147       FreeEdges.Clear();
0148     }
0149   };
0150 
0151   //! Runtime state of a cache slot.
0152   struct SlotState
0153   {
0154     SlotId   Slot       = DefaultDisplaySlot;
0155     uint64_t RecipeHash = 0;
0156     uint32_t Generation = 1;
0157     bool     HasDriver  = false;
0158   };
0159 
0160   //! Mesh recomputation driver registered by a meshing toolkit.
0161   class Driver : public Standard_Transient
0162   {
0163   public:
0164     [[nodiscard]] virtual const Standard_GUID& ID() const         = 0;
0165     [[nodiscard]] virtual uint64_t             RecipeHash() const = 0;
0166 
0167     [[nodiscard]] virtual bool Fill(BRepGraph&                   theGraph,
0168                                     SlotId                       theSlot,
0169                                     const DirtySet&              theDirtySet,
0170                                     const Message_ProgressRange& theRange) = 0;
0171 
0172     DEFINE_STANDARD_RTTIEXT(Driver, Standard_Transient)
0173   };
0174 
0175   Standard_EXPORT BRepGraph_CacheMesh();
0176 
0177   BRepGraph_CacheMesh(const BRepGraph_CacheMesh&)            = delete;
0178   BRepGraph_CacheMesh& operator=(const BRepGraph_CacheMesh&) = delete;
0179 
0180   //! Returns the unique cache service GUID.
0181   [[nodiscard]] static Standard_EXPORT const Standard_GUID& GetID();
0182 
0183   //! Returns the unique cache service GUID.
0184   [[nodiscard]] Standard_EXPORT const Standard_GUID& ID() const override;
0185 
0186   //! Returns the cache service display name.
0187   [[nodiscard]] Standard_EXPORT const TCollection_AsciiString& Name() const override;
0188 
0189   //! Clears all cache slots and registered drivers.
0190   Standard_EXPORT void Clear() noexcept override;
0191 
0192   //! Copy fresh, remappable mesh cache entries into the target graph.
0193   Standard_EXPORT void CopyFreshTo(const BRepGraph_CopyRemap& theCopy) const override;
0194 
0195   //! Get/set the currently active display slot.
0196   //! EffectiveView reads from this slot.
0197   [[nodiscard]] SlotId ActiveDisplaySlot() const { return myActiveSlot; }
0198 
0199   void SetActiveDisplaySlot(SlotId theSlot) { myActiveSlot = theSlot; }
0200 
0201   //! Register or replace a meshing driver for a cache slot.
0202   Standard_EXPORT void RegisterDriver(SlotId theSlot, const occ::handle<Driver>& theDriver);
0203 
0204   //! Remove a meshing driver from a cache slot and invalidate the slot.
0205   Standard_EXPORT void UnregisterDriver(SlotId theSlot);
0206 
0207   //! Return driver registered for a slot, or null.
0208   [[nodiscard]] Standard_EXPORT const occ::handle<Driver>& DriverOf(SlotId theSlot) const;
0209 
0210   //! Return current state of a cache slot.
0211   [[nodiscard]] Standard_EXPORT SlotState State(SlotId theSlot = DefaultDisplaySlot) const;
0212 
0213   //! Recompute stale data in a slot using its registered driver.
0214   [[nodiscard]] Standard_EXPORT bool Ensure(
0215     BRepGraph&                   theGraph,
0216     SlotId                       theSlot  = DefaultDisplaySlot,
0217     const Message_ProgressRange& theRange = Message_ProgressRange());
0218 
0219   //! Recompute stale data below a topology node using the slot driver.
0220   [[nodiscard]] Standard_EXPORT bool Ensure(
0221     BRepGraph&                   theGraph,
0222     const BRepGraph_NodeId       theRoot,
0223     SlotId                       theSlot  = DefaultDisplaySlot,
0224     const Message_ProgressRange& theRange = Message_ProgressRange());
0225 
0226   //! Recompute stale data for requested topology nodes using the slot driver.
0227   [[nodiscard]] Standard_EXPORT bool Ensure(
0228     BRepGraph&                                  theGraph,
0229     const NCollection_Array1<BRepGraph_NodeId>& theNodes,
0230     SlotId                                      theSlot  = DefaultDisplaySlot,
0231     const Message_ProgressRange&                theRange = Message_ProgressRange());
0232 
0233   //! Return true when a cache slot has stale or missing mesh below the topology node.
0234   //! Uses the same actualness rules as Ensure() but does not invoke the driver.
0235   [[nodiscard]] Standard_EXPORT bool Needs(BRepGraph&       theGraph,
0236                                            BRepGraph_NodeId theRoot,
0237                                            SlotId           theSlot = DefaultDisplaySlot) const;
0238 
0239   [[nodiscard]] Standard_EXPORT bool                 HasFaceMesh(BRepGraph_FaceId theFace) const;
0240   [[nodiscard]] Standard_EXPORT const FaceMeshEntry* FindFaceMesh(BRepGraph_FaceId theFace) const;
0241   [[nodiscard]] Standard_EXPORT FaceMeshEntry&       ChangeFaceMesh(BRepGraph_FaceId theFace);
0242   Standard_EXPORT void                               ClearFaceMesh(BRepGraph_FaceId theFace);
0243 
0244   [[nodiscard]] Standard_EXPORT bool             HasCoEdgeMesh(BRepGraph_CoEdgeId theCoEdge) const;
0245   [[nodiscard]] Standard_EXPORT CoEdgeMeshEntry& ChangeCoEdgeMesh(BRepGraph_CoEdgeId theCoEdge);
0246   Standard_EXPORT void                           ClearCoEdgeMesh(BRepGraph_CoEdgeId theCoEdge);
0247 
0248   [[nodiscard]] Standard_EXPORT bool                 HasEdgeMesh(BRepGraph_EdgeId theEdge) const;
0249   [[nodiscard]] Standard_EXPORT const EdgeMeshEntry* FindEdgeMesh(BRepGraph_EdgeId theEdge) const;
0250   [[nodiscard]] Standard_EXPORT EdgeMeshEntry&       ChangeEdgeMesh(BRepGraph_EdgeId theEdge);
0251   Standard_EXPORT void                               ClearEdgeMesh(BRepGraph_EdgeId theEdge);
0252 
0253   [[nodiscard]] Standard_EXPORT bool HasFaceMesh(SlotId theSlot, BRepGraph_FaceId theFace) const;
0254   [[nodiscard]] Standard_EXPORT const FaceMeshEntry* FindFaceMesh(SlotId           theSlot,
0255                                                                   BRepGraph_FaceId theFace) const;
0256   [[nodiscard]] Standard_EXPORT FaceMeshEntry&       ChangeFaceMesh(SlotId           theSlot,
0257                                                                     BRepGraph_FaceId theFace);
0258   Standard_EXPORT void ClearFaceMesh(SlotId theSlot, BRepGraph_FaceId theFace);
0259 
0260   [[nodiscard]] Standard_EXPORT bool             HasCoEdgeMesh(SlotId             theSlot,
0261                                                                BRepGraph_CoEdgeId theCoEdge) const;
0262   [[nodiscard]] Standard_EXPORT CoEdgeMeshEntry& ChangeCoEdgeMesh(SlotId             theSlot,
0263                                                                   BRepGraph_CoEdgeId theCoEdge);
0264   Standard_EXPORT void ClearCoEdgeMesh(SlotId theSlot, BRepGraph_CoEdgeId theCoEdge);
0265 
0266   [[nodiscard]] Standard_EXPORT bool HasEdgeMesh(SlotId theSlot, BRepGraph_EdgeId theEdge) const;
0267   [[nodiscard]] Standard_EXPORT const EdgeMeshEntry* FindEdgeMesh(SlotId           theSlot,
0268                                                                   BRepGraph_EdgeId theEdge) const;
0269   [[nodiscard]] Standard_EXPORT EdgeMeshEntry&       ChangeEdgeMesh(SlotId           theSlot,
0270                                                                     BRepGraph_EdgeId theEdge);
0271   Standard_EXPORT void ClearEdgeMesh(SlotId theSlot, BRepGraph_EdgeId theEdge);
0272 
0273   //! Stamp a freshly written default-slot entry.
0274   Standard_EXPORT void BindFresh(FaceMeshEntry& theEntry, BRepGraph_FaceId theFace) const;
0275   Standard_EXPORT void BindFresh(CoEdgeMeshEntry& theEntry, BRepGraph_CoEdgeId theCoEdge) const;
0276   Standard_EXPORT void BindFresh(EdgeMeshEntry& theEntry, BRepGraph_EdgeId theEdge) const;
0277 
0278   //! Bump face mesh generation after cached content changed.
0279   //! This is the ONLY mutator for MeshGeneration. ClearRepresentation() does not bump.
0280   //! Creates the face entry if it doesn't exist yet (via ensureSize).
0281   Standard_EXPORT void BumpFaceMeshGeneration(BRepGraph_FaceId theFace,
0282                                               SlotId           theSlot = DefaultDisplaySlot);
0283 
0284   //! Raw face entry access (no freshness filtering). For internal use.
0285   [[nodiscard]] Standard_EXPORT const FaceMeshEntry* findFaceEntryRaw(
0286     SlotId           theSlot,
0287     BRepGraph_FaceId theFace) const;
0288 
0289   //! Raw coedge entry access (no freshness/generation filtering).
0290   //! Returns nullptr if the slot is absent or the entry has no representation.
0291   //! For internal use.
0292   [[nodiscard]] Standard_EXPORT const CoEdgeMeshEntry* findCoEdgeEntryRaw(
0293     SlotId             theSlot,
0294     BRepGraph_CoEdgeId theCoEdge) const;
0295 
0296   //! Return coedge entry if Polygon2D is fresh, nullptr otherwise.
0297   [[nodiscard]] Standard_EXPORT const CoEdgeMeshEntry* FindCoEdgePolygon2D(
0298     SlotId             theSlot,
0299     BRepGraph_CoEdgeId theCoEdge) const;
0300 
0301   //! Return coedge entry if PolygonsOnTri is fresh, nullptr otherwise.
0302   [[nodiscard]] Standard_EXPORT const CoEdgeMeshEntry* FindCoEdgePolygonOnTri(
0303     SlotId             theSlot,
0304     BRepGraph_CoEdgeId theCoEdge) const;
0305 
0306   //! Return coedge entry if Polygon2D is fresh (default slot), nullptr otherwise.
0307   [[nodiscard]] Standard_EXPORT const CoEdgeMeshEntry* FindCoEdgePolygon2D(
0308     BRepGraph_CoEdgeId theCoEdge) const;
0309 
0310   //! Return coedge entry if PolygonsOnTri is fresh (default slot), nullptr otherwise.
0311   [[nodiscard]] Standard_EXPORT const CoEdgeMeshEntry* FindCoEdgePolygonOnTri(
0312     BRepGraph_CoEdgeId theCoEdge) const;
0313 
0314   DEFINE_STANDARD_RTTIEXT(BRepGraph_CacheMesh, BRepGraph_Cache)
0315 
0316 private:
0317   struct Slot;
0318 
0319   template <typename T>
0320   static void ensureSize(NCollection_DynamicArray<T>& theVec, size_t theIndex);
0321 
0322   [[nodiscard]] Slot&       changeSlot(SlotId theSlot);
0323   [[nodiscard]] const Slot* findSlot(SlotId theSlot) const;
0324 
0325   [[nodiscard]] bool isSlotActual(const Slot& theSlot, const EntryStamp& theStamp) const noexcept;
0326   void bindEntry(FaceMeshEntry& theEntry, BRepGraph_FaceId theFace, const Slot& theSlot) const;
0327   void bindEntry(CoEdgeMeshEntry&   theEntry,
0328                  BRepGraph_CoEdgeId theCoEdge,
0329                  const Slot&        theSlot) const;
0330   void bindEntry(EdgeMeshEntry& theEntry, BRepGraph_EdgeId theEdge, const Slot& theSlot) const;
0331 
0332   [[nodiscard]] bool isCoEdgePolygon2DFresh(const CoEdgeMeshEntry& theEntry,
0333                                             const Slot&            theSlot) const noexcept;
0334   [[nodiscard]] bool isCoEdgePolygonOnTriFresh(const CoEdgeMeshEntry& theEntry,
0335                                                const Slot&            theSlot) const noexcept;
0336   [[nodiscard]] bool isFaceMeshFresh(const CoEdgeMeshEntry& theEntry,
0337                                      const Slot&            theSlot) const noexcept;
0338 
0339   [[nodiscard]] const CoEdgeMeshEntry* findCoEdgeMesh(SlotId             theSlot,
0340                                                       BRepGraph_CoEdgeId theCoEdge) const;
0341 
0342   [[nodiscard]] DirtySet collectDirty(BRepGraph& theGraph, const Slot& theSlot) const;
0343   [[nodiscard]] DirtySet collectDirty(BRepGraph&             theGraph,
0344                                       const BRepGraph_NodeId theRoot,
0345                                       const Slot&            theSlot) const;
0346   [[nodiscard]] DirtySet collectDirty(BRepGraph&                                  theGraph,
0347                                       const NCollection_Array1<BRepGraph_NodeId>& theNodes,
0348                                       const Slot&                                 theSlot) const;
0349 
0350   NCollection_LinearVector<Slot> mySlots;
0351   SlotId                         myActiveSlot = DefaultDisplaySlot;
0352 };
0353 
0354 #endif // _BRepGraph_CacheMesh_HeaderFile