949df2b6 |
1 | // Created by: Peter KURNEV |
2 | // Copyright (c) 2014 OPEN CASCADE SAS |
3 | // |
4 | // This file is part of Open CASCADE Technology software library. |
5 | // |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
11 | // |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
14 | |
42cf5bc1 |
15 | |
16 | #include <BRep_Tool.hxx> |
17 | #include <BRepCheck.hxx> |
18 | #include <BRepCheck_ListOfStatus.hxx> |
19 | #include <BRepCheck_Solid.hxx> |
20 | #include <BRepClass3d_SolidClassifier.hxx> |
21 | #include <Geom_Curve.hxx> |
22 | #include <gp_Pnt.hxx> |
25e59720 |
23 | #include <Standard_Transient.hxx> |
949df2b6 |
24 | #include <NCollection_Map.hxx> |
42cf5bc1 |
25 | #include <NCollection_Vector.hxx> |
acb81c83 |
26 | #include <Precision.hxx> |
42cf5bc1 |
27 | #include <Standard_Type.hxx> |
28 | #include <TopExp_Explorer.hxx> |
29 | #include <TopoDS_Builder.hxx> |
30 | #include <TopoDS_Edge.hxx> |
31 | #include <TopoDS_Iterator.hxx> |
32 | #include <TopoDS_Shape.hxx> |
33 | #include <TopoDS_Shell.hxx> |
34 | #include <TopoDS_Solid.hxx> |
35 | #include <TopTools_MapOfShape.hxx> |
36 | #include <TopTools_ShapeMapHasher.hxx> |
37 | |
92efcf78 |
38 | IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Solid,BRepCheck_Result) |
39 | |
949df2b6 |
40 | // |
c04c30b3 |
41 | class BRepCheck_HSC; |
25e59720 |
42 | DEFINE_STANDARD_HANDLE(BRepCheck_HSC, Standard_Transient) |
949df2b6 |
43 | //======================================================================= |
44 | //class : BRepCheck_HSC |
45 | //purpose : |
46 | //======================================================================= |
25e59720 |
47 | class BRepCheck_HSC : public Standard_Transient { |
949df2b6 |
48 | public: |
49 | // |
50 | Standard_EXPORT |
51 | BRepCheck_HSC(){ |
52 | }; |
53 | // |
54 | Standard_EXPORT |
55 | virtual ~BRepCheck_HSC(){ |
56 | }; |
57 | // |
58 | Standard_EXPORT |
59 | BRepClass3d_SolidClassifier& SolidClassifier(){ |
60 | return mySC; |
61 | }; |
62 | // |
25e59720 |
63 | DEFINE_STANDARD_RTTI_INLINE(BRepCheck_HSC,Standard_Transient); |
949df2b6 |
64 | |
65 | protected: |
66 | BRepClass3d_SolidClassifier mySC; |
67 | }; |
ec357c5c |
68 | |
949df2b6 |
69 | // |
70 | //======================================================================= |
71 | //class : BRepCheck_ToolSolid |
72 | //purpose : |
73 | //======================================================================= |
74 | class BRepCheck_ToolSolid { |
75 | |
76 | public: |
77 | DEFINE_STANDARD_ALLOC |
78 | |
79 | BRepCheck_ToolSolid() { |
80 | myIsHole=Standard_False; |
acb81c83 |
81 | myPntTol=Precision::Confusion(); |
949df2b6 |
82 | myPnt.SetCoord(-1.,-1.,-1.); |
83 | }; |
84 | |
85 | virtual ~BRepCheck_ToolSolid() { |
86 | }; |
87 | // |
88 | void SetSolid(const TopoDS_Solid& aZ) { |
89 | mySolid=aZ; |
90 | }; |
91 | // |
92 | const TopoDS_Solid& Solid()const { |
93 | return mySolid; |
94 | }; |
95 | // |
96 | Standard_Boolean IsHole() const { |
97 | return myIsHole; |
98 | }; |
99 | // |
100 | const gp_Pnt& InnerPoint() { |
101 | return myPnt; |
102 | } |
103 | // |
acb81c83 |
104 | Standard_Real CheckTol() const { |
105 | return myPntTol; |
106 | }; |
107 | // |
949df2b6 |
108 | // IsOut |
109 | Standard_Boolean IsOut(BRepCheck_ToolSolid& aOther) { |
110 | Standard_Boolean bFlag; |
111 | TopAbs_State aState; |
112 | // |
113 | BRepClass3d_SolidClassifier& aSC=myHSC->SolidClassifier(); |
114 | // |
acb81c83 |
115 | aSC.Perform(aOther.InnerPoint(), aOther.CheckTol()); |
949df2b6 |
116 | aState=aSC.State(); |
117 | bFlag=(aState==TopAbs_OUT); |
118 | // |
119 | return bFlag; |
120 | }; |
121 | // |
122 | // Init |
123 | void Init() { |
124 | Standard_Real aT, aT1, aT2, aPAR_T; |
125 | TopExp_Explorer aExp; |
126 | // |
127 | // 0.myHSC |
128 | myHSC=new BRepCheck_HSC(); |
129 | // |
130 | BRepClass3d_SolidClassifier& aSC=myHSC->SolidClassifier(); |
131 | // 1. Load |
132 | aSC.Load(mySolid); |
133 | // |
134 | // 2. myIsHole |
135 | aSC.PerformInfinitePoint(::RealSmall()); |
136 | myIsHole=(aSC.State()==TopAbs_IN); |
137 | // |
138 | // 3. myPnt |
139 | aPAR_T=0.43213918; // 10*e^(-PI) |
140 | aExp.Init(mySolid, TopAbs_EDGE); |
141 | for (; aExp.More(); aExp.Next()) { |
142 | const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current()); |
143 | if (!BRep_Tool::Degenerated(aE)) { |
144 | Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aT1, aT2); |
145 | aT=(1.-aPAR_T)*aT1 + aPAR_T*aT2; |
146 | myPnt=aC3D->Value(aT); |
acb81c83 |
147 | myPntTol = BRep_Tool::Tolerance(aE); |
949df2b6 |
148 | break; |
149 | } |
150 | } |
151 | }; |
152 | // |
153 | protected: |
154 | Standard_Boolean myIsHole; |
acb81c83 |
155 | gp_Pnt myPnt; |
156 | Standard_Real myPntTol; |
949df2b6 |
157 | TopoDS_Solid mySolid; |
158 | Handle(BRepCheck_HSC) myHSC; |
159 | }; |
160 | // |
161 | typedef NCollection_Vector<BRepCheck_ToolSolid> |
162 | BRepCheck_VectorOfToolSolid; |
163 | // |
164 | |
165 | //======================================================================= |
166 | //function : BRepCheck_Solid |
167 | //purpose : |
168 | //======================================================================= |
169 | BRepCheck_Solid::BRepCheck_Solid (const TopoDS_Solid& S) |
170 | { |
171 | Init(S); |
172 | } |
173 | //======================================================================= |
174 | //function : Blind |
175 | //purpose : |
176 | //======================================================================= |
177 | void BRepCheck_Solid::Blind() |
178 | { |
179 | if (!myBlind) { |
180 | // nothing more than in the minimum |
181 | myBlind = Standard_True; |
182 | } |
183 | } |
184 | //======================================================================= |
185 | //function : InContext |
186 | //purpose : |
187 | //======================================================================= |
188 | void BRepCheck_Solid::InContext(const TopoDS_Shape& ) |
189 | { |
190 | } |
191 | //======================================================================= |
192 | //function : Minimum |
193 | //purpose : |
194 | //======================================================================= |
195 | void BRepCheck_Solid::Minimum() |
196 | { |
197 | if (myMin) { |
198 | return; |
199 | } |
200 | myMin = Standard_True; |
201 | // |
202 | Standard_Boolean bFound, bIsHole, bFlag; |
34a0b446 |
203 | Standard_Integer i, j, aNbVTS, aNbVTS1, iCntSh, iCntShInt; |
949df2b6 |
204 | TopoDS_Solid aZ; |
205 | TopoDS_Iterator aIt, aItF; |
206 | TopoDS_Builder aBB; |
207 | TopExp_Explorer aExp; |
208 | TopTools_MapOfShape aMSS; |
209 | TopAbs_Orientation aOr; |
210 | BRepCheck_VectorOfToolSolid aVTS; |
211 | BRepCheck_ListOfStatus thelist; |
212 | // |
213 | myMap.Bind(myShape, thelist); |
214 | BRepCheck_ListOfStatus& aLST = myMap(myShape); |
215 | aLST.Append(BRepCheck_NoError); |
216 | // |
217 | //------------------------------------------------- |
218 | // 1. InvalidImbricationOfShells |
219 | bFound=Standard_False; |
220 | aExp.Init(myShape, TopAbs_FACE); |
221 | for (; !bFound && aExp.More(); aExp.Next()) { |
222 | const TopoDS_Shape& aF=aExp.Current(); |
223 | if (!aMSS.Add(aF)) { |
224 | BRepCheck::Add(myMap(myShape), |
225 | BRepCheck_InvalidImbricationOfShells); |
226 | bFound=!bFound; |
227 | } |
228 | } |
229 | // |
230 | //------------------------------------------------- |
231 | // 2. |
232 | // - Too many growths, |
233 | // - There is smt of the solid that is out of solid |
34a0b446 |
234 | iCntSh=0; |
235 | iCntShInt=0; |
949df2b6 |
236 | aIt.Initialize(myShape); |
237 | for (; aIt.More(); aIt.Next()) { |
238 | const TopoDS_Shape& aSx=aIt.Value(); |
239 | // |
240 | if (aSx.ShapeType()!=TopAbs_SHELL) { |
241 | aOr=aSx.Orientation(); |
242 | if (aOr!=TopAbs_INTERNAL) { |
243 | BRepCheck::Add(myMap(myShape), |
244 | BRepCheck_BadOrientationOfSubshape); |
245 | } |
246 | continue; |
247 | } |
248 | // |
249 | const TopoDS_Shell& aSh=*((TopoDS_Shell*)&aSx); |
250 | // |
251 | // Skip internal shells |
252 | bFound=Standard_False; |
253 | aItF.Initialize(aSh); |
254 | for (; !bFound && aItF.More(); aItF.Next()) { |
255 | const TopoDS_Shape& aF=aItF.Value(); |
256 | aOr=aF.Orientation(); |
257 | if (aOr==TopAbs_INTERNAL) { |
258 | bFound=!bFound; |
259 | } |
260 | } |
261 | if (bFound) { |
34a0b446 |
262 | ++iCntShInt; |
949df2b6 |
263 | continue; |
264 | } |
265 | // |
34a0b446 |
266 | ++iCntSh; |
267 | // |
949df2b6 |
268 | // Skip not closed shells |
269 | if (!BRep_Tool::IsClosed(aSh)) { |
270 | continue; |
271 | } |
272 | // |
273 | aBB.MakeSolid(aZ); |
274 | aBB.Add(aZ, aSh); |
275 | // |
276 | BRepCheck_ToolSolid aTS; |
277 | // |
278 | aTS.SetSolid(aZ); |
279 | aVTS.Append(aTS); |
280 | }//for (; aIt.More(); aIt.Next()) { |
281 | // |
34a0b446 |
282 | if (!iCntSh && iCntShInt) { |
283 | // all shells in the solid are internal |
284 | BRepCheck::Add(myMap(myShape), |
285 | BRepCheck_BadOrientationOfSubshape); |
286 | } |
287 | // |
949df2b6 |
288 | aNbVTS=aVTS.Size(); |
289 | if (aNbVTS<2) { |
290 | return; |
291 | } |
292 | // |
293 | aNbVTS1=0; |
294 | for (i=0; i<aNbVTS; ++i) { |
295 | BRepCheck_ToolSolid& aTS=aVTS(i); |
296 | // |
297 | aTS.Init(); |
298 | bIsHole=aTS.IsHole(); |
299 | if (!bIsHole) { |
300 | ++aNbVTS1; |
301 | if (aNbVTS1>1) { |
302 | // Too many growths |
303 | BRepCheck::Add(myMap(myShape), |
304 | BRepCheck_EnclosedRegion); |
305 | break; |
306 | } |
307 | } |
308 | } |
309 | // |
310 | bFound=Standard_False; |
311 | aNbVTS1=aNbVTS-1; |
312 | for (i=0; !bFound && i<aNbVTS1; ++i) { |
313 | BRepCheck_ToolSolid& aTSi=aVTS(i); |
314 | // |
315 | for (j=i+1; !bFound && j<aNbVTS; ++j) { |
316 | BRepCheck_ToolSolid& aTSj=aVTS(j); |
317 | // |
318 | bFlag=aTSi.IsOut(aTSj); |
319 | if (bFlag) { |
320 | // smt of solid is out of solid |
321 | BRepCheck::Add(myMap(myShape), |
322 | BRepCheck_SubshapeNotInShape); |
323 | bFound=!bFound; |
324 | } |
325 | } |
326 | } |
327 | // |
328 | //myMin = Standard_True; |
329 | } |