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