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