// Created on: 2007-11-24 // Created by: Alexander GRIGORIEV // Copyright (c) 2007-2014 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 Poly_CoherentTriangulation_HeaderFile #define Poly_CoherentTriangulation_HeaderFile #include "Poly_Triangulation.hxx" #include "Poly_CoherentNode.hxx" #include "Poly_CoherentTriangle.hxx" #include "Poly_CoherentLink.hxx" #include "NCollection_DynamicArray.hxx" class Poly_CoherentTriangulation; template class NCollection_List; //! Definition of HANDLE object using Standard_DefineHandle.hxx #include "Standard_Type.hxx" /** * Triangulation structure that allows to: * * * This class is useful for algorithms that need to analyse and/or edit a triangulated mesh -- for * example for mesh refining. The connectivity model follows the idea that all Triangles in a mesh * should have coherent orientation like on a surface of a solid body. Connections between more than * 2 triangles are not supported. * * @section Poly_CoherentTriangulation Architecture * The data types used in this structure are: * */ class Poly_CoherentTriangulation : public Standard_Transient { public: /** * Subclass Iterator - allows to iterate all triangles skipping those that * have been removed. */ class IteratorOfTriangle : public NCollection_DynamicArray::Iterator { public: //! Constructor Standard_EXPORT IteratorOfTriangle(const occ::handle& theTri); //! Make step Standard_EXPORT void Next() noexcept override; }; /** * Subclass Iterator - allows to iterate all nodes skipping the free ones. */ class IteratorOfNode : public NCollection_DynamicArray::Iterator { public: //! Constructor Standard_EXPORT IteratorOfNode(const occ::handle& theTri); //! Make step Standard_EXPORT void Next() noexcept override; }; /** * Subclass Iterator - allows to iterate all links skipping invalid ones. */ class IteratorOfLink : public NCollection_DynamicArray::Iterator { public: //! Constructor Standard_EXPORT IteratorOfLink(const occ::handle& theTri); //! Make step Standard_EXPORT void Next() noexcept override; }; //! Couple of integer indices (used in RemoveDegenerated()). struct TwoIntegers { int myValue[2]; TwoIntegers() = default; TwoIntegers(int i0, int i1) { myValue[0] = i0; myValue[1] = i1; } }; public: // ---------- PUBLIC METHODS ---------- /** * Empty constructor. */ Standard_EXPORT Poly_CoherentTriangulation( const occ::handle& theAlloc = nullptr); /** * Constructor. It does not create Links, you should call ComputeLinks * following this constructor if you need these links. */ Standard_EXPORT Poly_CoherentTriangulation( const occ::handle& theTriangulation, const occ::handle& theAlloc = nullptr); /** * Destructor. */ Standard_EXPORT ~Poly_CoherentTriangulation() override; /** * Create an instance of Poly_Triangulation from this object. */ Standard_EXPORT occ::handle GetTriangulation() const; /** * Find and remove degenerated triangles in Triangulation. * @param theTol * Tolerance for the degeneration case. If any two nodes of a triangle have * the distance less than this tolerance, this triangle is considered * degenerated and therefore removed by this method. * @param pLstRemovedNode * Optional parameter. If defined, then it will receive the list of arrays * where the first number is the index of removed node and the second - * the index of remaining node to which the mesh was reconnected. */ Standard_EXPORT bool RemoveDegenerated(const double theTol, NCollection_List* pLstRemovedNode = nullptr); /** * Create a list of free nodes. These nodes may appear as a result of any * custom mesh decimation or RemoveDegenerated() call. This analysis is * necessary if you support additional data structures based on the * triangulation (e.g., edges on the surface boundary). * @param lstNodes * [out] List that receives the indices of free nodes. */ Standard_EXPORT bool GetFreeNodes(NCollection_List& lstNodes) const; /** * Query the index of the last node in the triangulation */ inline int MaxNode() const { return myNodes.Length() - 1; } /** * Query the index of the last triangle in the triangulation */ inline int MaxTriangle() const { return myTriangles.Length() - 1; } /** * Set the Deflection value as the parameter of the given triangulation. */ inline void SetDeflection(const double theDefl) { myDeflection = theDefl; } /** * Query the Deflection parameter (default value 0. -- if never initialized) */ inline double Deflection() const { return myDeflection; } /** * Initialize a node * @param thePoint * 3D Coordinates of the node. * @param iN * Index of the node. If negative (default), the node is added to the * end of the current array of nodes. * @return * Index of the added node. */ Standard_EXPORT int SetNode(const gp_XYZ& thePnt, const int iN = -1); /** * Get the node at the given index 'i'. */ inline const Poly_CoherentNode& Node(const int i) const { return myNodes.Value(i); } /** * Get the node at the given index 'i'. */ inline Poly_CoherentNode& ChangeNode(const int i) { return myNodes.ChangeValue(i); } /** * Query the total number of active nodes (i.e. nodes used by 1 or more * triangles) */ Standard_EXPORT int NNodes() const; /** * Get the triangle at the given index 'i'. */ inline const Poly_CoherentTriangle& Triangle(const int i) const { return myTriangles.Value(i); } /** * Query the total number of active triangles (i.e. triangles that refer * nodes, non-empty ones) */ Standard_EXPORT int NTriangles() const; /** * Query the total number of active Links. */ Standard_EXPORT int NLinks() const; /** * Removal of a single triangle from the triangulation. */ Standard_EXPORT bool RemoveTriangle(Poly_CoherentTriangle& theTr); /** * Removal of a single link from the triangulation. */ Standard_EXPORT void RemoveLink(Poly_CoherentLink& theLink); /** * Add a triangle to the triangulation. * @return * Pointer to the added triangle instance or NULL if an error occurred. */ Standard_EXPORT Poly_CoherentTriangle* AddTriangle(const int iNode0, const int iNode1, const int iNode2); /** * Replace nodes in the given triangle. * @return * True if operation succeeded. */ Standard_EXPORT bool ReplaceNodes(Poly_CoherentTriangle& theTriangle, const int iNode0, const int iNode1, const int iNode2); /** * Add a single link to triangulation, based on a triangle and its side index. * This method does not check for coincidence with already present links. * @param theTri * Triangle that contains the link to be added. * @param theConn * Index of the side (i.e., 0, 1 0r 2) defining the added link. */ Standard_EXPORT Poly_CoherentLink* AddLink(const Poly_CoherentTriangle& theTri, const int theConn); /** * Find one or two triangles that share the given couple of nodes. * @param theLink * Link (in fact, just a couple of nodes) on which the triangle is * searched. * @param pTri * [out] Array of two pointers to triangle. pTri[0] stores the * triangle to the left of the link, while pTri[1] stores the one to the * right of the link. * @return * True if at least one triangle is found and output as pTri. */ Standard_EXPORT bool FindTriangle(const Poly_CoherentLink& theLink, const Poly_CoherentTriangle* pTri[2]) const; /** * (Re)Calculate all links in this Triangulation. */ Standard_EXPORT int ComputeLinks(); /** * Clear all Links data from the Triangulation data. */ Standard_EXPORT void ClearLinks(); /** * Query the allocator of elements, this allocator can be used for other * objects */ inline const occ::handle& Allocator() const { return myAlloc; } /** * Create a copy of this Triangulation, using the given allocator. */ Standard_EXPORT occ::handle Clone( const occ::handle& theAlloc) const; /** * Debugging output. */ Standard_EXPORT void Dump(Standard_OStream&) const; protected: // ---------- PROTECTED FIELDS ---------- NCollection_DynamicArray myTriangles; NCollection_DynamicArray myNodes; NCollection_DynamicArray myLinks; occ::handle myAlloc; double myDeflection; public: // Declaration of CASCADE RTTI DEFINE_STANDARD_RTTIEXT(Poly_CoherentTriangulation, Standard_Transient) friend class IteratorOfTriangle; friend class IteratorOfNode; friend class IteratorOfLink; }; #endif