Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:03:14

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