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