0025113: Mesh - Progress indication and user break functionality for BRepMesh component
[occt.git] / src / BRepMesh / BRepMesh_ModelHealer.hxx
1 // Created on: 2016-06-23
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_ModelHealer_HeaderFile
17 #define _BRepMesh_ModelHealer_HeaderFile
18
19 #include <IMeshTools_ModelAlgo.hxx>
20 #include <IMeshTools_Parameters.hxx>
21 #include <IMeshData_Types.hxx>
22 #include <IMeshData_Model.hxx>
23 #include <TopoDS_Vertex.hxx>
24
25 //! Class implements functionality of model healer tool.
26 //! Iterates over model's faces and checks consistency of their wires, 
27 //! i.e.whether wires are closed and do not contain self - intersections.
28 //! In case if wire contains disconnected parts, ends of adjacent edges
29 //! forming the gaps are connected in parametric space forcibly. The notion
30 //! of this operation is to create correct discrete model defined relatively
31 //! parametric space of target face taking into account connectivity and 
32 //! tolerances of 3D space only. This means that there are no specific 
33 //! computations are made for the sake of determination of U and V tolerance.
34 //! Registers intersections on edges forming the face's shape and tries to
35 //! amplify discrete represenation by decreasing of deflection for the target edge.
36 //! Checks can be performed in parallel mode.
37 class BRepMesh_ModelHealer : public IMeshTools_ModelAlgo
38 {
39 public:
40
41   //! Constructor.
42   Standard_EXPORT BRepMesh_ModelHealer();
43
44   //! Destructor.
45   Standard_EXPORT virtual ~BRepMesh_ModelHealer();
46
47   //! Functor API to discretize the given edge.
48   inline void operator() (const Standard_Integer theEdgeIndex) const {
49     process(theEdgeIndex);
50   }
51
52   //! Functor API to discretize the given edge.
53   inline void operator() (const IMeshData::IFaceHandle& theDFace) const {
54     process(theDFace);
55   }
56
57   DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelHealer, IMeshTools_ModelAlgo)
58
59 protected:
60
61   //! Performs processing of edges of the given model.
62   Standard_EXPORT virtual Standard_Boolean performInternal (
63     const Handle(IMeshData_Model)& theModel,
64     const IMeshTools_Parameters&   theParameters,
65     const Message_ProgressRange&   theRange) Standard_OVERRIDE;
66
67 private:
68
69   //! Checks existing discretization of the face and updates data model.
70   inline void process(const Standard_Integer theFaceIndex) const
71   {
72     const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
73     process(aDFace);
74   }
75
76   //! Checks existing discretization of the face and updates data model.
77   void process(const IMeshData::IFaceHandle& theDFace) const;
78
79   //! Amplifies discretization of edges in case if self-intersection problem has been found.
80   void amplifyEdges();
81
82   //! Returns common vertex of two edges or null ptr in case if there is no such vertex.
83   TopoDS_Vertex getCommonVertex(
84     const IMeshData::IEdgeHandle& theEdge1,
85     const IMeshData::IEdgeHandle& theEdge2) const;
86
87   //! Connects pcurves of previous and current edge on the specified face 
88   //! according to topological connectivity. Uses next edge in order to
89   //! identify closest point in case of signle vertex shared between both
90   //! ends of edge (degenerative edge)
91   Standard_Boolean connectClosestPoints(
92     const IMeshData::IPCurveHandle& thePrevDEdge,
93     const IMeshData::IPCurveHandle& theCurrDEdge,
94     const IMeshData::IPCurveHandle& theNextDEdge) const;
95
96   //! Chooses the most closest point to reference one from the given pair.
97   //! Returns square distance between reference point and closest one as 
98   //! well as pointer to closest point.
99   inline Standard_Real closestPoint(
100     gp_Pnt2d&  theRefPnt,
101     gp_Pnt2d&  theFristPnt,
102     gp_Pnt2d&  theSecondPnt,
103     gp_Pnt2d*& theClosestPnt) const
104   {
105     // Find the most closest end-points.
106     const Standard_Real aSqDist1 = theRefPnt.SquareDistance(theFristPnt);
107     const Standard_Real aSqDist2 = theRefPnt.SquareDistance(theSecondPnt);
108     if (aSqDist1 < aSqDist2)
109     {
110       theClosestPnt = &theFristPnt;
111       return aSqDist1;
112     }
113
114     theClosestPnt = &theSecondPnt;
115     return aSqDist2;
116   }
117
118   //! Chooses the most closest points among the given to reference one from the given pair.
119   //! Returns square distance between reference point and closest one as 
120   //! well as pointer to closest point.
121   inline Standard_Real closestPoints(
122     gp_Pnt2d&  theFirstPnt1,
123     gp_Pnt2d&  theSecondPnt1,
124     gp_Pnt2d&  theFirstPnt2,
125     gp_Pnt2d&  theSecondPnt2,
126     gp_Pnt2d*& theClosestPnt1,
127     gp_Pnt2d*& theClosestPnt2) const
128   {
129     gp_Pnt2d *aCurrPrevUV1 = NULL, *aCurrPrevUV2 = NULL;
130     const Standard_Real aSqDist1 = closestPoint(theFirstPnt1,  theFirstPnt2, theSecondPnt2, aCurrPrevUV1);
131     const Standard_Real aSqDist2 = closestPoint(theSecondPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV2);
132     if (aSqDist1 - aSqDist2 < gp::Resolution())
133     {
134       theClosestPnt1 = &theFirstPnt1;
135       theClosestPnt2 = aCurrPrevUV1;
136       return aSqDist1;
137     }
138
139     theClosestPnt1 = &theSecondPnt1;
140     theClosestPnt2 = aCurrPrevUV2;
141     return aSqDist2;
142   }
143
144   //! Adjusts the given pair of points supposed to be the same.
145   //! In addition, adjusts another end-point of an edge in order
146   //! to perform correct matching in case of gap.
147   inline void adjustSamePoints(
148     gp_Pnt2d*& theMajorSamePnt1,
149     gp_Pnt2d*& theMinorSamePnt1,
150     gp_Pnt2d*& theMajorSamePnt2,
151     gp_Pnt2d*& theMinorSamePnt2,
152     gp_Pnt2d&  theMajorFirstPnt,
153     gp_Pnt2d&  theMajorLastPnt,
154     gp_Pnt2d&  theMinorFirstPnt,
155     gp_Pnt2d&  theMinorLastPnt) const
156   {
157     if (theMajorSamePnt2 == theMajorSamePnt1)
158     {
159       theMajorSamePnt2 = (theMajorSamePnt2 == &theMajorFirstPnt) ? &theMajorLastPnt : &theMajorFirstPnt;
160       closestPoint(*theMajorSamePnt2, theMinorFirstPnt, theMinorLastPnt, theMinorSamePnt2);
161     }
162
163     *theMajorSamePnt1 = *theMinorSamePnt1;
164     *theMajorSamePnt2 = *theMinorSamePnt2;
165   }
166
167   //! Connects ends of pcurves of face's wires according to topological coherency.
168   void fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const;
169
170   //! Returns True if check can be done in parallel.
171   inline Standard_Boolean isParallel() const
172   {
173     return (myParameters.InParallel && myModel->FacesNb() > 1);
174   }
175
176   //! Collects unique edges to be updated from face map. Clears data stored in face map.
177   Standard_Boolean popEdgesToUpdate(IMeshData::MapOfIEdgePtr& theEdgesToUpdate);
178
179 private:
180
181   Handle(IMeshData_Model)                           myModel;
182   IMeshTools_Parameters                             myParameters;
183   Handle(IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs)  myFaceIntersectingEdges;
184 };
185
186 #endif