0026106: BRepMesh - revision of data model
[occt.git] / src / BRepMesh / BRepMesh_MeshTool.hxx
1 // Created on: 2016-08-22
2 // Copyright (c) 2016 OPEN CASCADE SAS
3 // Created by: Oleg AGASHIN
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _BRepMesh_MeshTool_HeaderFile
17 #define _BRepMesh_MeshTool_HeaderFile
18
19 #include <Standard_Transient.hxx>
20 #include <Standard_DefineHandle.hxx>
21 #include <BRepMesh_DataStructureOfDelaun.hxx>
22 #include <BRepMesh_CircleTool.hxx>
23 #include <gp_Lin2d.hxx>
24 #include <IMeshData_Types.hxx>
25 #include <BRepMesh_Edge.hxx>
26
27 #include <stack>
28
29 //! Auxiliary tool providing API for manipulation with BRepMesh_DataStructureOfDelaun.
30 class BRepMesh_MeshTool : public Standard_Transient
31 {
32 public:
33
34   //! Helper functor intended to separate points to left and right from the constraint.
35   class NodeClassifier
36   {
37   public:
38
39     NodeClassifier(
40       const BRepMesh_Edge&                          theConstraint,
41       const Handle(BRepMesh_DataStructureOfDelaun)& theStructure)
42       : myStructure(theStructure)
43     {
44       const BRepMesh_Vertex& aVertex1 = myStructure->GetNode(theConstraint.FirstNode());
45       const BRepMesh_Vertex& aVertex2 = myStructure->GetNode(theConstraint.LastNode());
46
47       myConstraint.SetLocation(aVertex1.Coord());
48       myConstraint.SetDirection(gp_Vec2d(aVertex1.Coord(), aVertex2.Coord()));
49       mySign = myConstraint.Direction().X() > 0;
50     }
51
52     inline Standard_Boolean IsAbove(const Standard_Integer theNodeIndex) const
53     {
54       const BRepMesh_Vertex& aVertex = myStructure->GetNode(theNodeIndex);
55       const gp_Vec2d aNodeVec(myConstraint.Location(), aVertex.Coord());
56       if (aNodeVec.SquareMagnitude() > gp::Resolution())
57       {
58         const Standard_Real aCross = aNodeVec.Crossed(myConstraint.Direction());
59         if (Abs(aCross) > gp::Resolution())
60         {
61           return mySign ? 
62             aCross < 0. :
63             aCross > 0.;
64         }
65       }
66
67       return Standard_False;
68     }
69
70   private:
71
72     NodeClassifier (const NodeClassifier& theOther);
73
74     void operator=(const NodeClassifier& theOther);
75
76   private:
77
78     const Handle(BRepMesh_DataStructureOfDelaun)& myStructure;
79     gp_Lin2d                                      myConstraint;
80     Standard_Boolean                              mySign;
81   };
82
83   //! Constructor.
84   //! Initializes tool by the given data structure.
85   Standard_EXPORT BRepMesh_MeshTool(const Handle(BRepMesh_DataStructureOfDelaun)& theStructure);
86
87   //! Destructor.
88   Standard_EXPORT virtual ~BRepMesh_MeshTool();
89
90   //! Returns data structure manipulated by this tool.
91   inline const Handle(BRepMesh_DataStructureOfDelaun)& GetStructure() const
92   {
93     return myStructure;
94   }
95
96   //! Dumps triangles to specified file.
97   void DumpTriangles(const Standard_CString theFileName, IMeshData::MapOfInteger* theTriangles);
98
99   //! Adds new triangle with specified nodes to mesh.
100   //! Legalizes triangle in case if it violates circle criteria.
101   inline void AddAndLegalizeTriangle(
102     const Standard_Integer thePoint1,
103     const Standard_Integer thePoint2,
104     const Standard_Integer thePoint3)
105   {
106     Standard_Integer aEdges[3];
107     AddTriangle(thePoint1, thePoint2, thePoint3, aEdges);
108
109     Legalize(aEdges[0]);
110     Legalize(aEdges[1]);
111     Legalize(aEdges[2]);
112   }
113
114   //! Adds new triangle with specified nodes to mesh.
115   inline void AddTriangle(
116     const Standard_Integer thePoint1,
117     const Standard_Integer thePoint2,
118     const Standard_Integer thePoint3,
119     Standard_Integer     (&theEdges)[3])
120   {
121     Standard_Boolean aOri[3];
122     AddLink(thePoint1, thePoint2, theEdges[0], aOri[0]);
123     AddLink(thePoint2, thePoint3, theEdges[1], aOri[1]);
124     AddLink(thePoint3, thePoint1, theEdges[2], aOri[2]);
125
126     myStructure->AddElement(BRepMesh_Triangle(theEdges, aOri, BRepMesh_Free));
127   }
128
129   //! Adds new link to mesh.
130   //! Updates link index and link orientaion parameters.
131   inline void AddLink(const Standard_Integer theFirstNode,
132                       const Standard_Integer theLastNode,
133                       Standard_Integer&      theLinkIndex,
134                       Standard_Boolean&      theLinkOri)
135   {
136     const Standard_Integer aLinkIt = myStructure->AddLink(
137       BRepMesh_Edge(theFirstNode, theLastNode, BRepMesh_Free));
138
139     theLinkIndex = Abs(aLinkIt);
140     theLinkOri = (aLinkIt > 0);
141   }
142
143   //! Performs legalization of triangles connected to the specified link.
144   Standard_EXPORT void Legalize(const Standard_Integer theLinkIndex);
145
146   //! Erases all elements connected to the specified artificial node.
147   //! In addition, erases the artificial node itself.
148   Standard_EXPORT void EraseItemsConnectedTo(const Standard_Integer theNodeIndex);
149
150   //! Cleans frontier links from triangles to the right.
151   Standard_EXPORT void CleanFrontierLinks();
152
153   //! Erases the given set of triangles.
154   //! Fills map of loop edges forming the countour surrounding the erased triangles.
155   void EraseTriangles(const IMeshData::MapOfInteger&  theTriangles,
156                       IMeshData::MapOfIntegerInteger& theLoopEdges);
157
158   //! Erases triangle with the given index and adds the free edges into the map.
159   //! When an edge is suppressed more than one time it is destroyed.
160   Standard_EXPORT void EraseTriangle(const Standard_Integer          theTriangleIndex,
161                                      IMeshData::MapOfIntegerInteger& theLoopEdges);
162
163   //! Erases all links that have no elements connected to them.
164   Standard_EXPORT void EraseFreeLinks();
165
166   //! Erases links from the specified map that have no elements connected to them.
167   Standard_EXPORT void EraseFreeLinks(const IMeshData::MapOfIntegerInteger& theLinks);
168
169   //! Gives the list of edges with type defined by input parameter.
170   Standard_EXPORT Handle(IMeshData::MapOfInteger) GetEdgesByType(const BRepMesh_DegreeOfFreedom theEdgeType) const;
171
172   DEFINE_STANDARD_RTTI_INLINE(BRepMesh_MeshTool, Standard_Transient)
173
174 private:
175
176   //! Returns True if the given point lies within circumcircle of the given triangle.
177   inline Standard_Boolean checkCircle(
178     const Standard_Integer(&aNodes)[3],
179     const Standard_Integer thePoint)
180   {
181     const BRepMesh_Vertex& aVertex0 = myStructure->GetNode(aNodes[0]);
182     const BRepMesh_Vertex& aVertex1 = myStructure->GetNode(aNodes[1]);
183     const BRepMesh_Vertex& aVertex2 = myStructure->GetNode(aNodes[2]);
184
185     gp_XY aLocation;
186     Standard_Real aRadius;
187     const Standard_Boolean isOk = BRepMesh_CircleTool::MakeCircle(
188       aVertex0.Coord(), aVertex1.Coord(), aVertex2.Coord(),
189       aLocation, aRadius);
190
191     if (isOk)
192     {
193       const BRepMesh_Vertex& aVertex = myStructure->GetNode(thePoint);
194       const Standard_Real aDist = (aVertex.Coord() - aLocation).SquareModulus() - (aRadius * aRadius);
195       return (aDist < Precision::SquareConfusion());
196     }
197
198     return Standard_False;
199   }
200
201   //! Adds new triangle with the given nodes and updates
202   //! links stack by ones are not in used map.
203   inline void addTriangleAndUpdateStack(
204     const Standard_Integer         theNode0,
205     const Standard_Integer         theNode1,
206     const Standard_Integer         theNode2,
207     const IMeshData::MapOfInteger& theUsedLinks,
208     std::stack<Standard_Integer>&  theStack)
209   {
210     Standard_Integer aEdges[3];
211     AddTriangle(theNode0, theNode1, theNode2, aEdges);
212
213     for (Standard_Integer i = 0; i < 3; ++i)
214     {
215       if (!theUsedLinks.Contains(aEdges[i]))
216       {
217         theStack.push(aEdges[i]);
218       }
219     }
220   }
221
222   //! Iteratively erases triangles and their neighbours consisting
223   //! of free links using the given link as starting front.
224   //! Only triangles around the constraint's saddle nodes will be removed.
225   void collectTrianglesOnFreeLinksAroundNodesOf(
226     const BRepMesh_Edge&     theConstraint,
227     const Standard_Integer   theStartLink,
228     IMeshData::MapOfInteger& theTriangles);
229
230 private:
231
232   Handle(BRepMesh_DataStructureOfDelaun) myStructure;
233 };
234
235 #endif