Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-25 09:21:01

0001 // Created on: 2007-11-24
0002 // Created by: Alexander GRIGORIEV
0003 // Copyright (c) 2007-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef Poly_CoherentTriangulation_HeaderFile
0017 #define Poly_CoherentTriangulation_HeaderFile
0018 
0019 #include <Poly_Triangulation.hxx>
0020 #include <Poly_CoherentNode.hxx>
0021 #include <Poly_CoherentTriangle.hxx>
0022 #include <Poly_CoherentLink.hxx>
0023 #include <NCollection_DynamicArray.hxx>
0024 
0025 class Poly_CoherentTriangulation;
0026 template <class A>
0027 class NCollection_List;
0028 
0029 //! Definition of HANDLE object using Standard_DefineHandle.hxx
0030 #include <Standard_Type.hxx>
0031 
0032 /**
0033  * Triangulation structure that allows to:
0034  * <ul>
0035  * <li>Store the connectivity of each triangle with up to 3 neighbouring ones and with the
0036  * corresponding 3rd nodes on them,</li> <li>Store the connectivity of each node with all triangles
0037  * that share this node</li> <li>Add nodes and triangles to the structure,</li> <li>Find all
0038  * triangles sharing a single or a couple of nodes</li> <li>Remove triangles from structure</li>
0039  * <li>Optionally create Links between pairs of nodes according to the current triangulation.</li>
0040  * <li>Convert from/to Poly_Triangulation structure.</li>
0041  * </ul>
0042  *
0043  * This class is useful for algorithms that need to analyse and/or edit a triangulated mesh -- for
0044  * example for mesh refining. The connectivity model follows the idea that all Triangles in a mesh
0045  * should have coherent orientation like on a surface of a solid body. Connections between more than
0046  * 2 triangles are not supported.
0047  *
0048  * @section Poly_CoherentTriangulation Architecture
0049  * The data types used in this structure are:
0050  * <ul>
0051  * <li><b>Poly_CoherentNode</b>: Inherits go_XYZ therefore provides the full public API of gp_XYZ.
0052  * Contains references to all incident triangles. You can add new nodes but you cannot remove
0053  * existing ones. However each node that has no referenced triangle is considered as "free" (use the
0054  * method IsFreeNode() to check this). Free nodes are not available to further processing,
0055  * particularly they are not exported in Poly_Triangulation.
0056  * </li>
0057  * <li><b>Poly_CoherentTriangle</b>: Main data type. Refers three Nodes, three connected Triangles,
0058  * three opposite (connected) Nodes and three Links. If there is boundary then 1, 2 or 3 references
0059  * to Triangles/connected Nodes/Links are assigned to NULL (for pointers) or -1 (for integer node
0060  * index).
0061  *
0062  * You can find a triangle by one node using its triangle iterator or by
0063  * two nodes - creating a temporary Poly_CoherentLink and calling the method FindTriangle().
0064  *
0065  * Triangles can be removed but they are never deleted from the containing array. Removed triangles
0066  * have all nodes equal to -1. You can use the method IsEmpty() to check that.
0067  * </li>
0068  * <li><b>Poly_CoherentLink</b>: Auxiliary data type. Normally the array of Links is empty, because
0069  * for many algorithms it is sufficient to define only Triangles. You can explicitly create the
0070  * Links at least once, calling the method ComputeLinks(). Each Link is oriented couple of
0071  * Poly_CoherentNode (directed to the ascending Node index). It refers two connected triangulated
0072  * Nodes - on the left and on the right, therefore a Poly_CoherentLink instance refers the full set
0073  * of nodes that constitute a couple of connected Triangles. A boundary Link has either the first
0074  * (left) or the second (right) connected node index equal to -1.
0075  *
0076  * When the array of Links is created, all subsequent calls to AddTriangle and RemoveTriangle try to
0077  * preserve the connectivity Triangle-Link in addition to the connectivity Triangle-Triangle.
0078  * Particularly, new Links are created by method AddTriangle() and existing ones are removed by
0079  * method RemoveTriangle(), in each case whenever necessary.
0080  *
0081  * Similarly to Poly_CoherentTriangle, a Link can be removed but not destroyed separately from
0082  * others. Removed Link can be recogniosed using the method IsEmpty(). To destroy all Links, call
0083  * the method ClearLinks(), this method also nullifies Link references in all Triangles.
0084  * </li>
0085  * All objects (except for free Nodes and empty Triangles and Links) can be visited by the
0086  * corresponding Iterator. Direct access is provided only for Nodes (needed to resolve Node indexed
0087  * commonly used as reference). Triangles and Links can be retrieved by their index only internally,
0088  * the public API provides only references or pointers to C++ objects. If you need a direct access
0089  * to Triangles and Links, you can subclass Poly_CoherentTriangulation and use the protected API for
0090  * your needs.
0091  *
0092  * Memory management: All data objects are stored in NCollection_DynamicArray containers that prove
0093  * to be efficient for the performance. In addition references to triangles are stored in ring
0094  * lists, with an instance of such list per Poly_CoherentNode. These lists are allocated in a memory
0095  * allocator that is provided in the constructor of Poly_CoherentTriangulation. By default the
0096  * standard OCCT allocator (aka NCollection_BaseAllocator) is used. But if you need to increase the
0097  * performance you can use NCollection_IncAllocator instead.
0098  * </ul>
0099  */
0100 class Poly_CoherentTriangulation : public Standard_Transient
0101 {
0102 public:
0103   /**
0104    * Subclass Iterator - allows to iterate all triangles skipping those that
0105    * have been removed.
0106    */
0107   class IteratorOfTriangle : public NCollection_DynamicArray<Poly_CoherentTriangle>::Iterator
0108   {
0109   public:
0110     //! Constructor
0111     Standard_EXPORT IteratorOfTriangle(const occ::handle<Poly_CoherentTriangulation>& theTri);
0112     //! Make step
0113     Standard_EXPORT void Next() noexcept override;
0114   };
0115 
0116   /**
0117    * Subclass Iterator - allows to iterate all nodes skipping the free ones.
0118    */
0119   class IteratorOfNode : public NCollection_DynamicArray<Poly_CoherentNode>::Iterator
0120   {
0121   public:
0122     //! Constructor
0123     Standard_EXPORT IteratorOfNode(const occ::handle<Poly_CoherentTriangulation>& theTri);
0124     //! Make step
0125     Standard_EXPORT void Next() noexcept override;
0126   };
0127 
0128   /**
0129    * Subclass Iterator - allows to iterate all links skipping invalid ones.
0130    */
0131   class IteratorOfLink : public NCollection_DynamicArray<Poly_CoherentLink>::Iterator
0132   {
0133   public:
0134     //! Constructor
0135     Standard_EXPORT IteratorOfLink(const occ::handle<Poly_CoherentTriangulation>& theTri);
0136     //! Make step
0137     Standard_EXPORT void Next() noexcept override;
0138   };
0139 
0140   //! Couple of integer indices (used in RemoveDegenerated()).
0141   struct TwoIntegers
0142   {
0143     int myValue[2];
0144 
0145     TwoIntegers() = default;
0146 
0147     TwoIntegers(int i0, int i1)
0148     {
0149       myValue[0] = i0;
0150       myValue[1] = i1;
0151     }
0152   };
0153 
0154 public:
0155   // ---------- PUBLIC METHODS ----------
0156 
0157   /**
0158    * Empty constructor.
0159    */
0160   Standard_EXPORT Poly_CoherentTriangulation(
0161     const occ::handle<NCollection_BaseAllocator>& theAlloc = nullptr);
0162 
0163   /**
0164    * Constructor. It does not create Links, you should call ComputeLinks
0165    * following this constructor if you need these links.
0166    */
0167   Standard_EXPORT Poly_CoherentTriangulation(
0168     const occ::handle<Poly_Triangulation>&        theTriangulation,
0169     const occ::handle<NCollection_BaseAllocator>& theAlloc = nullptr);
0170 
0171   /**
0172    * Destructor.
0173    */
0174   Standard_EXPORT ~Poly_CoherentTriangulation() override;
0175 
0176   /**
0177    * Create an instance of Poly_Triangulation from this object.
0178    */
0179   Standard_EXPORT occ::handle<Poly_Triangulation> GetTriangulation() const;
0180 
0181   /**
0182    * Find and remove degenerated triangles in Triangulation.
0183    * @param theTol
0184    *   Tolerance for the degeneration case. If any two nodes of a triangle have
0185    *   the distance less than this tolerance, this triangle is considered
0186    *   degenerated and therefore removed by this method.
0187    * @param pLstRemovedNode
0188    *   Optional parameter. If defined, then it will receive the list of arrays
0189    *   where the first number is the index of removed node and the second -
0190    *   the index of remaining node to which the mesh was reconnected.
0191    */
0192   Standard_EXPORT bool RemoveDegenerated(const double                   theTol,
0193                                          NCollection_List<TwoIntegers>* pLstRemovedNode = nullptr);
0194 
0195   /**
0196    * Create a list of free nodes. These nodes may appear as a result of any
0197    * custom mesh decimation or RemoveDegenerated() call. This analysis is
0198    * necessary if you support additional data structures based on the
0199    * triangulation (e.g., edges on the surface boundary).
0200    * @param lstNodes
0201    *   <tt>[out]</tt> List that receives the indices of free nodes.
0202    */
0203   Standard_EXPORT bool GetFreeNodes(NCollection_List<int>& lstNodes) const;
0204 
0205   /**
0206    * Query the index of the last node in the triangulation
0207    */
0208   inline int MaxNode() const { return myNodes.Length() - 1; }
0209 
0210   /**
0211    * Query the index of the last triangle in the triangulation
0212    */
0213   inline int MaxTriangle() const { return myTriangles.Length() - 1; }
0214 
0215   /**
0216    * Set the Deflection value as the parameter of the given triangulation.
0217    */
0218   inline void SetDeflection(const double theDefl) { myDeflection = theDefl; }
0219 
0220   /**
0221    * Query the Deflection parameter (default value 0. -- if never initialized)
0222    */
0223   inline double Deflection() const { return myDeflection; }
0224 
0225   /**
0226    * Initialize a node
0227    * @param thePoint
0228    *   3D Coordinates of the node.
0229    * @param iN
0230    *   Index of the node. If negative (default), the node is added to the
0231    *   end of the current array of nodes.
0232    * @return
0233    *   Index of the added node.
0234    */
0235   Standard_EXPORT int SetNode(const gp_XYZ& thePnt, const int iN = -1);
0236 
0237   /**
0238    * Get the node at the given index 'i'.
0239    */
0240   inline const Poly_CoherentNode& Node(const int i) const { return myNodes.Value(i); }
0241 
0242   /**
0243    * Get the node at the given index 'i'.
0244    */
0245   inline Poly_CoherentNode& ChangeNode(const int i) { return myNodes.ChangeValue(i); }
0246 
0247   /**
0248    * Query the total number of active nodes (i.e. nodes used by 1 or more
0249    * triangles)
0250    */
0251   Standard_EXPORT int NNodes() const;
0252 
0253   /**
0254    * Get the triangle at the given index 'i'.
0255    */
0256   inline const Poly_CoherentTriangle& Triangle(const int i) const { return myTriangles.Value(i); }
0257 
0258   /**
0259    * Query the total number of active triangles (i.e. triangles that refer
0260    * nodes, non-empty ones)
0261    */
0262   Standard_EXPORT int NTriangles() const;
0263 
0264   /**
0265    * Query the total number of active Links.
0266    */
0267   Standard_EXPORT int NLinks() const;
0268 
0269   /**
0270    * Removal of a single triangle from the triangulation.
0271    */
0272   Standard_EXPORT bool RemoveTriangle(Poly_CoherentTriangle& theTr);
0273 
0274   /**
0275    * Removal of a single link from the triangulation.
0276    */
0277   Standard_EXPORT void RemoveLink(Poly_CoherentLink& theLink);
0278 
0279   /**
0280    * Add a triangle to the triangulation.
0281    * @return
0282    *   Pointer to the added triangle instance or NULL if an error occurred.
0283    */
0284   Standard_EXPORT Poly_CoherentTriangle* AddTriangle(const int iNode0,
0285                                                      const int iNode1,
0286                                                      const int iNode2);
0287 
0288   /**
0289    * Replace nodes in the given triangle.
0290    * @return
0291    *   True if operation succeeded.
0292    */
0293   Standard_EXPORT bool ReplaceNodes(Poly_CoherentTriangle& theTriangle,
0294                                     const int              iNode0,
0295                                     const int              iNode1,
0296                                     const int              iNode2);
0297 
0298   /**
0299    * Add a single link to triangulation, based on a triangle and its side index.
0300    * This method does not check for coincidence with already present links.
0301    * @param theTri
0302    *   Triangle that contains the link to be added.
0303    * @param theConn
0304    *   Index of the side (i.e., 0, 1 0r 2) defining the added link.
0305    */
0306   Standard_EXPORT Poly_CoherentLink* AddLink(const Poly_CoherentTriangle& theTri,
0307                                              const int                    theConn);
0308 
0309   /**
0310    * Find one or two triangles that share the given couple of nodes.
0311    * @param theLink
0312    *   Link (in fact, just a couple of nodes) on which the triangle is
0313    *   searched.
0314    * @param pTri
0315    *   <tt>[out]</tt> Array of two pointers to triangle. pTri[0] stores the
0316    *   triangle to the left of the link, while pTri[1] stores the one to the
0317    *   right of the link.
0318    * @return
0319    *   True if at least one triangle is found and output as pTri.
0320    */
0321   Standard_EXPORT bool FindTriangle(const Poly_CoherentLink&     theLink,
0322                                     const Poly_CoherentTriangle* pTri[2]) const;
0323 
0324   /**
0325    * (Re)Calculate all links in this Triangulation.
0326    */
0327   Standard_EXPORT int ComputeLinks();
0328 
0329   /**
0330    * Clear all Links data from the Triangulation data.
0331    */
0332   Standard_EXPORT void ClearLinks();
0333 
0334   /**
0335    * Query the allocator of elements, this allocator can be used for other
0336    * objects
0337    */
0338   inline const occ::handle<NCollection_BaseAllocator>& Allocator() const { return myAlloc; }
0339 
0340   /**
0341    * Create a copy of this Triangulation, using the given allocator.
0342    */
0343   Standard_EXPORT occ::handle<Poly_CoherentTriangulation> Clone(
0344     const occ::handle<NCollection_BaseAllocator>& theAlloc) const;
0345 
0346   /**
0347    * Debugging output.
0348    */
0349   Standard_EXPORT void Dump(Standard_OStream&) const;
0350 
0351 protected:
0352   // ---------- PROTECTED FIELDS ----------
0353 
0354   NCollection_DynamicArray<Poly_CoherentTriangle> myTriangles;
0355   NCollection_DynamicArray<Poly_CoherentNode>     myNodes;
0356   NCollection_DynamicArray<Poly_CoherentLink>     myLinks;
0357   occ::handle<NCollection_BaseAllocator>          myAlloc;
0358   double                                          myDeflection;
0359 
0360 public:
0361   // Declaration of CASCADE RTTI
0362   DEFINE_STANDARD_RTTIEXT(Poly_CoherentTriangulation, Standard_Transient)
0363 
0364   friend class IteratorOfTriangle;
0365   friend class IteratorOfNode;
0366   friend class IteratorOfLink;
0367 };
0368 
0369 #endif