Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-09 09:15:04

0001 // Created on: 2016-08-22
0002 // Copyright (c) 2016 OPEN CASCADE SAS
0003 // Created by: Oleg AGASHIN
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 _BRepMesh_MeshTool_HeaderFile
0017 #define _BRepMesh_MeshTool_HeaderFile
0018 
0019 #include <Standard_Transient.hxx>
0020 #include <BRepMesh_DataStructureOfDelaun.hxx>
0021 #include <BRepMesh_CircleTool.hxx>
0022 #include <gp_Lin2d.hxx>
0023 #include <IMeshData_Types.hxx>
0024 #include <BRepMesh_Edge.hxx>
0025 
0026 #include <stack>
0027 
0028 //! Auxiliary tool providing API for manipulation with BRepMesh_DataStructureOfDelaun.
0029 class BRepMesh_MeshTool : public Standard_Transient
0030 {
0031 public:
0032   //! Helper functor intended to separate points to left and right from the constraint.
0033   class NodeClassifier
0034   {
0035   public:
0036     NodeClassifier(const BRepMesh_Edge&                          theConstraint,
0037                    const Handle(BRepMesh_DataStructureOfDelaun)& theStructure)
0038         : myStructure(theStructure)
0039     {
0040       const BRepMesh_Vertex& aVertex1 = myStructure->GetNode(theConstraint.FirstNode());
0041       const BRepMesh_Vertex& aVertex2 = myStructure->GetNode(theConstraint.LastNode());
0042 
0043       myConstraint.SetLocation(aVertex1.Coord());
0044       myConstraint.SetDirection(gp_Vec2d(aVertex1.Coord(), aVertex2.Coord()));
0045       mySign = myConstraint.Direction().X() > 0;
0046     }
0047 
0048     Standard_Boolean IsAbove(const Standard_Integer theNodeIndex) const
0049     {
0050       const BRepMesh_Vertex& aVertex = myStructure->GetNode(theNodeIndex);
0051       const gp_Vec2d         aNodeVec(myConstraint.Location(), aVertex.Coord());
0052       if (aNodeVec.SquareMagnitude() > gp::Resolution())
0053       {
0054         const Standard_Real aCross = aNodeVec.Crossed(myConstraint.Direction());
0055         if (Abs(aCross) > gp::Resolution())
0056         {
0057           return mySign ? aCross < 0. : aCross > 0.;
0058         }
0059       }
0060 
0061       return Standard_False;
0062     }
0063 
0064   private:
0065     NodeClassifier(const NodeClassifier& theOther);
0066 
0067     void operator=(const NodeClassifier& theOther);
0068 
0069   private:
0070     const Handle(BRepMesh_DataStructureOfDelaun)& myStructure;
0071     gp_Lin2d                                      myConstraint;
0072     Standard_Boolean                              mySign;
0073   };
0074 
0075   //! Constructor.
0076   //! Initializes tool by the given data structure.
0077   Standard_EXPORT BRepMesh_MeshTool(const Handle(BRepMesh_DataStructureOfDelaun)& theStructure);
0078 
0079   //! Destructor.
0080   Standard_EXPORT virtual ~BRepMesh_MeshTool();
0081 
0082   //! Returns data structure manipulated by this tool.
0083   const Handle(BRepMesh_DataStructureOfDelaun)& GetStructure() const { return myStructure; }
0084 
0085   //! Dumps triangles to specified file.
0086   void DumpTriangles(const Standard_CString theFileName, IMeshData::MapOfInteger* theTriangles);
0087 
0088   //! Adds new triangle with specified nodes to mesh.
0089   //! Legalizes triangle in case if it violates circle criteria.
0090   void AddAndLegalizeTriangle(const Standard_Integer thePoint1,
0091                               const Standard_Integer thePoint2,
0092                               const Standard_Integer thePoint3)
0093   {
0094     Standard_Integer aEdges[3];
0095     AddTriangle(thePoint1, thePoint2, thePoint3, aEdges);
0096 
0097     Legalize(aEdges[0]);
0098     Legalize(aEdges[1]);
0099     Legalize(aEdges[2]);
0100   }
0101 
0102   //! Adds new triangle with specified nodes to mesh.
0103   void AddTriangle(const Standard_Integer thePoint1,
0104                    const Standard_Integer thePoint2,
0105                    const Standard_Integer thePoint3,
0106                    Standard_Integer (&theEdges)[3])
0107   {
0108     Standard_Boolean aOri[3];
0109     AddLink(thePoint1, thePoint2, theEdges[0], aOri[0]);
0110     AddLink(thePoint2, thePoint3, theEdges[1], aOri[1]);
0111     AddLink(thePoint3, thePoint1, theEdges[2], aOri[2]);
0112 
0113     myStructure->AddElement(BRepMesh_Triangle(theEdges, aOri, BRepMesh_Free));
0114   }
0115 
0116   //! Adds new link to mesh.
0117   //! Updates link index and link orientation parameters.
0118   void AddLink(const Standard_Integer theFirstNode,
0119                const Standard_Integer theLastNode,
0120                Standard_Integer&      theLinkIndex,
0121                Standard_Boolean&      theLinkOri)
0122   {
0123     const Standard_Integer aLinkIt =
0124       myStructure->AddLink(BRepMesh_Edge(theFirstNode, theLastNode, BRepMesh_Free));
0125 
0126     theLinkIndex = Abs(aLinkIt);
0127     theLinkOri   = (aLinkIt > 0);
0128   }
0129 
0130   //! Performs legalization of triangles connected to the specified link.
0131   Standard_EXPORT void Legalize(const Standard_Integer theLinkIndex);
0132 
0133   //! Erases all elements connected to the specified artificial node.
0134   //! In addition, erases the artificial node itself.
0135   Standard_EXPORT void EraseItemsConnectedTo(const Standard_Integer theNodeIndex);
0136 
0137   //! Cleans frontier links from triangles to the right.
0138   Standard_EXPORT void CleanFrontierLinks();
0139 
0140   //! Erases the given set of triangles.
0141   //! Fills map of loop edges forming the contour surrounding the erased triangles.
0142   void EraseTriangles(const IMeshData::MapOfInteger&  theTriangles,
0143                       IMeshData::MapOfIntegerInteger& theLoopEdges);
0144 
0145   //! Erases triangle with the given index and adds the free edges into the map.
0146   //! When an edge is suppressed more than one time it is destroyed.
0147   Standard_EXPORT void EraseTriangle(const Standard_Integer          theTriangleIndex,
0148                                      IMeshData::MapOfIntegerInteger& theLoopEdges);
0149 
0150   //! Erases all links that have no elements connected to them.
0151   Standard_EXPORT void EraseFreeLinks();
0152 
0153   //! Erases links from the specified map that have no elements connected to them.
0154   Standard_EXPORT void EraseFreeLinks(const IMeshData::MapOfIntegerInteger& theLinks);
0155 
0156   //! Gives the list of edges with type defined by input parameter.
0157   Standard_EXPORT Handle(IMeshData::MapOfInteger) GetEdgesByType(
0158     const BRepMesh_DegreeOfFreedom theEdgeType) const;
0159 
0160   DEFINE_STANDARD_RTTIEXT(BRepMesh_MeshTool, Standard_Transient)
0161 
0162 private:
0163   //! Returns True if the given point lies within circumcircle of the given triangle.
0164   Standard_Boolean checkCircle(const Standard_Integer (&aNodes)[3], const Standard_Integer thePoint)
0165   {
0166     const BRepMesh_Vertex& aVertex0 = myStructure->GetNode(aNodes[0]);
0167     const BRepMesh_Vertex& aVertex1 = myStructure->GetNode(aNodes[1]);
0168     const BRepMesh_Vertex& aVertex2 = myStructure->GetNode(aNodes[2]);
0169 
0170     gp_XY                  aLocation;
0171     Standard_Real          aRadius;
0172     const Standard_Boolean isOk = BRepMesh_CircleTool::MakeCircle(aVertex0.Coord(),
0173                                                                   aVertex1.Coord(),
0174                                                                   aVertex2.Coord(),
0175                                                                   aLocation,
0176                                                                   aRadius);
0177 
0178     if (isOk)
0179     {
0180       const BRepMesh_Vertex& aVertex = myStructure->GetNode(thePoint);
0181       const Standard_Real    aDist =
0182         (aVertex.Coord() - aLocation).SquareModulus() - (aRadius * aRadius);
0183       return (aDist < Precision::SquareConfusion());
0184     }
0185 
0186     return Standard_False;
0187   }
0188 
0189   //! Adds new triangle with the given nodes and updates
0190   //! links stack by ones are not in used map.
0191   void addTriangleAndUpdateStack(const Standard_Integer         theNode0,
0192                                  const Standard_Integer         theNode1,
0193                                  const Standard_Integer         theNode2,
0194                                  const IMeshData::MapOfInteger& theUsedLinks,
0195                                  std::stack<Standard_Integer>&  theStack)
0196   {
0197     Standard_Integer aEdges[3];
0198     AddTriangle(theNode0, theNode1, theNode2, aEdges);
0199 
0200     for (Standard_Integer i = 0; i < 3; ++i)
0201     {
0202       if (!theUsedLinks.Contains(aEdges[i]))
0203       {
0204         theStack.push(aEdges[i]);
0205       }
0206     }
0207   }
0208 
0209   //! Iteratively erases triangles and their neighbours consisting
0210   //! of free links using the given link as starting front.
0211   //! Only triangles around the constraint's saddle nodes will be removed.
0212   void collectTrianglesOnFreeLinksAroundNodesOf(const BRepMesh_Edge&     theConstraint,
0213                                                 const Standard_Integer   theStartLink,
0214                                                 IMeshData::MapOfInteger& theTriangles);
0215 
0216 private:
0217   Handle(BRepMesh_DataStructureOfDelaun) myStructure;
0218 };
0219 
0220 #endif