7bd071ed |
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 | |
4945e8be |
52 | Standard_Boolean IsAbove(const Standard_Integer theNodeIndex) const |
7bd071ed |
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. |
4945e8be |
91 | const Handle(BRepMesh_DataStructureOfDelaun)& GetStructure() const |
7bd071ed |
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. |
4945e8be |
101 | void AddAndLegalizeTriangle( |
7bd071ed |
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. |
4945e8be |
115 | void AddTriangle( |
7bd071ed |
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. |
21c7c457 |
130 | //! Updates link index and link orientation parameters. |
4945e8be |
131 | void AddLink(const Standard_Integer theFirstNode, |
132 | const Standard_Integer theLastNode, |
133 | Standard_Integer& theLinkIndex, |
134 | Standard_Boolean& theLinkOri) |
7bd071ed |
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 | |
4945e8be |
172 | DEFINE_STANDARD_RTTIEXT(BRepMesh_MeshTool, Standard_Transient) |
7bd071ed |
173 | |
174 | private: |
175 | |
176 | //! Returns True if the given point lies within circumcircle of the given triangle. |
4945e8be |
177 | Standard_Boolean checkCircle( |
7bd071ed |
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. |
4945e8be |
203 | void addTriangleAndUpdateStack( |
7bd071ed |
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 |